From f5d5898dc4df9c6ed7d6323d78257b2a4f7f626a Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2025 16:26:06 +0200 Subject: [PATCH] Update 2025-04-13_16:26:04 --- __pycache__/main.cpython-311.pyc | Bin 0 -> 1883 bytes main.py | 30 + static/app.js | 71 + static/emoji.js | 45 + static/index.html | 30 + static/ollama.js | 35 + static/style.css | 93 + venv/bin/Activate.ps1 | 247 + venv/bin/activate | 69 + venv/bin/activate.csh | 26 + venv/bin/activate.fish | 69 + venv/bin/fastapi | 8 + venv/bin/pip | 8 + venv/bin/pip3 | 8 + venv/bin/pip3.11 | 8 + venv/bin/python | 1 + venv/bin/python3 | 1 + venv/bin/python3.11 | 1 + venv/bin/uvicorn | 8 + .../MarkupSafe-3.0.2.dist-info/INSTALLER | 1 + .../MarkupSafe-3.0.2.dist-info/LICENSE.txt | 28 + .../MarkupSafe-3.0.2.dist-info/METADATA | 92 + .../MarkupSafe-3.0.2.dist-info/RECORD | 14 + .../MarkupSafe-3.0.2.dist-info/WHEEL | 6 + .../MarkupSafe-3.0.2.dist-info/top_level.txt | 1 + .../typing_extensions.cpython-311.pyc | Bin 0 -> 189002 bytes .../site-packages/_distutils_hack/__init__.py | 222 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 11159 bytes .../__pycache__/override.cpython-311.pyc | Bin 0 -> 316 bytes .../site-packages/_distutils_hack/override.py | 1 + .../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-311.pyc | Bin 0 -> 20561 bytes .../__pycache__/test_cases.cpython-311.pyc | Bin 0 -> 15452 bytes .../site-packages/annotated_types/py.typed | 0 .../annotated_types/test_cases.py | 151 + .../anyio-4.9.0.dist-info/INSTALLER | 1 + .../anyio-4.9.0.dist-info/LICENSE | 20 + .../anyio-4.9.0.dist-info/METADATA | 105 + .../anyio-4.9.0.dist-info/RECORD | 88 + .../site-packages/anyio-4.9.0.dist-info/WHEEL | 5 + .../anyio-4.9.0.dist-info/entry_points.txt | 2 + .../anyio-4.9.0.dist-info/top_level.txt | 1 + .../site-packages/anyio/__init__.py | 85 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 4748 bytes .../__pycache__/from_thread.cpython-311.pyc | Bin 0 -> 26166 bytes .../__pycache__/lowlevel.cpython-311.pyc | Bin 0 -> 7645 bytes .../__pycache__/pytest_plugin.cpython-311.pyc | Bin 0 -> 15177 bytes .../to_interpreter.cpython-311.pyc | Bin 0 -> 10016 bytes .../__pycache__/to_process.cpython-311.pyc | Bin 0 -> 13664 bytes .../__pycache__/to_thread.cpython-311.pyc | Bin 0 -> 3187 bytes .../site-packages/anyio/_backends/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 194 bytes .../__pycache__/_asyncio.cpython-311.pyc | Bin 0 -> 146193 bytes .../__pycache__/_trio.cpython-311.pyc | Bin 0 -> 77884 bytes .../site-packages/anyio/_backends/_asyncio.py | 2816 ++++++ .../site-packages/anyio/_backends/_trio.py | 1334 +++ .../site-packages/anyio/_core/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 190 bytes .../_asyncio_selector_thread.cpython-311.pyc | Bin 0 -> 9088 bytes .../__pycache__/_eventloop.cpython-311.pyc | Bin 0 -> 6925 bytes .../__pycache__/_exceptions.cpython-311.pyc | Bin 0 -> 7195 bytes .../_core/__pycache__/_fileio.cpython-311.pyc | Bin 0 -> 42160 bytes .../__pycache__/_resources.cpython-311.pyc | Bin 0 -> 1114 bytes .../__pycache__/_signals.cpython-311.pyc | Bin 0 -> 1359 bytes .../__pycache__/_sockets.cpython-311.pyc | Bin 0 -> 32706 bytes .../__pycache__/_streams.cpython-311.pyc | Bin 0 -> 2655 bytes .../__pycache__/_subprocesses.cpython-311.pyc | Bin 0 -> 9821 bytes .../_synchronization.cpython-311.pyc | Bin 0 -> 35713 bytes .../_core/__pycache__/_tasks.cpython-311.pyc | Bin 0 -> 7700 bytes .../__pycache__/_tempfile.cpython-311.pyc | Bin 0 -> 28595 bytes .../__pycache__/_testing.cpython-311.pyc | Bin 0 -> 3870 bytes .../__pycache__/_typedattr.cpython-311.pyc | Bin 0 -> 4412 bytes .../anyio/_core/_asyncio_selector_thread.py | 167 + .../site-packages/anyio/_core/_eventloop.py | 166 + .../site-packages/anyio/_core/_exceptions.py | 126 + .../site-packages/anyio/_core/_fileio.py | 742 ++ .../site-packages/anyio/_core/_resources.py | 18 + .../site-packages/anyio/_core/_signals.py | 27 + .../site-packages/anyio/_core/_sockets.py | 792 ++ .../site-packages/anyio/_core/_streams.py | 52 + .../anyio/_core/_subprocesses.py | 202 + .../anyio/_core/_synchronization.py | 732 ++ .../site-packages/anyio/_core/_tasks.py | 158 + .../site-packages/anyio/_core/_tempfile.py | 616 ++ .../site-packages/anyio/_core/_testing.py | 78 + .../site-packages/anyio/_core/_typedattr.py | 81 + .../site-packages/anyio/abc/__init__.py | 55 + .../abc/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2891 bytes .../__pycache__/_eventloop.cpython-311.pyc | Bin 0 -> 16445 bytes .../__pycache__/_resources.cpython-311.pyc | Bin 0 -> 1822 bytes .../abc/__pycache__/_sockets.cpython-311.pyc | Bin 0 -> 11213 bytes .../abc/__pycache__/_streams.cpython-311.pyc | Bin 0 -> 9609 bytes .../__pycache__/_subprocesses.cpython-311.pyc | Bin 0 -> 3669 bytes .../abc/__pycache__/_tasks.cpython-311.pyc | Bin 0 -> 4993 bytes .../abc/__pycache__/_testing.cpython-311.pyc | Bin 0 -> 3030 bytes .../site-packages/anyio/abc/_eventloop.py | 376 + .../site-packages/anyio/abc/_resources.py | 33 + .../site-packages/anyio/abc/_sockets.py | 194 + .../site-packages/anyio/abc/_streams.py | 203 + .../site-packages/anyio/abc/_subprocesses.py | 79 + .../site-packages/anyio/abc/_tasks.py | 101 + .../site-packages/anyio/abc/_testing.py | 65 + .../site-packages/anyio/from_thread.py | 527 + .../site-packages/anyio/lowlevel.py | 161 + .../python3.11/site-packages/anyio/py.typed | 0 .../site-packages/anyio/pytest_plugin.py | 272 + .../site-packages/anyio/streams/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 192 bytes .../__pycache__/buffered.cpython-311.pyc | Bin 0 -> 6492 bytes .../streams/__pycache__/file.cpython-311.pyc | Bin 0 -> 8133 bytes .../__pycache__/memory.cpython-311.pyc | Bin 0 -> 15970 bytes .../__pycache__/stapled.cpython-311.pyc | Bin 0 -> 8259 bytes .../streams/__pycache__/text.cpython-311.pyc | Bin 0 -> 9014 bytes .../streams/__pycache__/tls.cpython-311.pyc | Bin 0 -> 18414 bytes .../site-packages/anyio/streams/buffered.py | 119 + .../site-packages/anyio/streams/file.py | 148 + .../site-packages/anyio/streams/memory.py | 317 + .../site-packages/anyio/streams/stapled.py | 141 + .../site-packages/anyio/streams/text.py | 147 + .../site-packages/anyio/streams/tls.py | 352 + .../site-packages/anyio/to_interpreter.py | 218 + .../site-packages/anyio/to_process.py | 258 + .../site-packages/anyio/to_thread.py | 69 + .../bcrypt-4.3.0.dist-info/INSTALLER | 1 + .../bcrypt-4.3.0.dist-info/LICENSE | 201 + .../bcrypt-4.3.0.dist-info/METADATA | 330 + .../bcrypt-4.3.0.dist-info/RECORD | 12 + .../bcrypt-4.3.0.dist-info/REQUESTED | 0 .../bcrypt-4.3.0.dist-info/WHEEL | 5 + .../bcrypt-4.3.0.dist-info/top_level.txt | 1 + .../site-packages/bcrypt/__init__.py | 43 + .../site-packages/bcrypt/__init__.pyi | 10 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 718 bytes .../site-packages/bcrypt/_bcrypt.abi3.so | Bin 0 -> 644928 bytes .../python3.11/site-packages/bcrypt/py.typed | 0 .../click-8.1.8.dist-info/INSTALLER | 1 + .../click-8.1.8.dist-info/LICENSE.txt | 28 + .../click-8.1.8.dist-info/METADATA | 74 + .../click-8.1.8.dist-info/RECORD | 38 + .../site-packages/click-8.1.8.dist-info/WHEEL | 4 + .../site-packages/click/__init__.py | 75 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3726 bytes .../click/__pycache__/_compat.cpython-311.pyc | Bin 0 -> 28668 bytes .../__pycache__/_termui_impl.cpython-311.pyc | Bin 0 -> 33269 bytes .../__pycache__/_textwrap.cpython-311.pyc | Bin 0 -> 2638 bytes .../__pycache__/_winconsole.cpython-311.pyc | Bin 0 -> 13328 bytes .../click/__pycache__/core.cpython-311.pyc | Bin 0 -> 142557 bytes .../__pycache__/decorators.cpython-311.pyc | Bin 0 -> 26330 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 16346 bytes .../__pycache__/formatting.cpython-311.pyc | Bin 0 -> 15683 bytes .../click/__pycache__/globals.cpython-311.pyc | Bin 0 -> 3348 bytes .../click/__pycache__/parser.cpython-311.pyc | Bin 0 -> 23127 bytes .../shell_completion.cpython-311.pyc | Bin 0 -> 24123 bytes .../click/__pycache__/termui.cpython-311.pyc | Bin 0 -> 34472 bytes .../click/__pycache__/testing.cpython-311.pyc | Bin 0 -> 25963 bytes .../click/__pycache__/types.cpython-311.pyc | Bin 0 -> 53706 bytes .../click/__pycache__/utils.cpython-311.pyc | Bin 0 -> 28034 bytes .../python3.11/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 788 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../python3.11/site-packages/click/core.py | 3047 ++++++ .../site-packages/click/decorators.py | 562 ++ .../site-packages/click/exceptions.py | 296 + .../site-packages/click/formatting.py | 301 + .../python3.11/site-packages/click/globals.py | 67 + .../python3.11/site-packages/click/parser.py | 531 + .../python3.11/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 603 ++ .../python3.11/site-packages/click/termui.py | 784 ++ .../python3.11/site-packages/click/testing.py | 483 + .../python3.11/site-packages/click/types.py | 1093 +++ .../python3.11/site-packages/click/utils.py | 624 ++ .../site-packages/distutils-precedence.pth | 1 + .../fastapi-0.115.12.dist-info/INSTALLER | 1 + .../fastapi-0.115.12.dist-info/METADATA | 565 ++ .../fastapi-0.115.12.dist-info/RECORD | 97 + .../fastapi-0.115.12.dist-info/REQUESTED | 0 .../fastapi-0.115.12.dist-info/WHEEL | 4 + .../entry_points.txt | 5 + .../licenses/LICENSE | 21 + .../site-packages/fastapi/__init__.py | 25 + .../site-packages/fastapi/__main__.py | 3 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1401 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 269 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 32753 bytes .../__pycache__/applications.cpython-311.pyc | Bin 0 -> 92513 bytes .../__pycache__/background.cpython-311.pyc | Bin 0 -> 2567 bytes .../fastapi/__pycache__/cli.cpython-311.pyc | Bin 0 -> 764 bytes .../__pycache__/concurrency.cpython-311.pyc | Bin 0 -> 1863 bytes .../datastructures.cpython-311.pyc | Bin 0 -> 9392 bytes .../__pycache__/encoders.cpython-311.pyc | Bin 0 -> 12450 bytes .../exception_handlers.cpython-311.pyc | Bin 0 -> 2343 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8256 bytes .../__pycache__/logger.cpython-311.pyc | Bin 0 -> 284 bytes .../param_functions.cpython-311.pyc | Bin 0 -> 41433 bytes .../__pycache__/params.cpython-311.pyc | Bin 0 -> 29242 bytes .../__pycache__/requests.cpython-311.pyc | Bin 0 -> 303 bytes .../__pycache__/responses.cpython-311.pyc | Bin 0 -> 2755 bytes .../__pycache__/routing.cpython-311.pyc | Bin 0 -> 92508 bytes .../__pycache__/staticfiles.cpython-311.pyc | Bin 0 -> 260 bytes .../__pycache__/templating.cpython-311.pyc | Bin 0 -> 262 bytes .../__pycache__/testclient.cpython-311.pyc | Bin 0 -> 257 bytes .../fastapi/__pycache__/types.cpython-311.pyc | Bin 0 -> 917 bytes .../fastapi/__pycache__/utils.cpython-311.pyc | Bin 0 -> 9396 bytes .../__pycache__/websockets.cpython-311.pyc | Bin 0 -> 367 bytes .../site-packages/fastapi/_compat.py | 659 ++ .../site-packages/fastapi/applications.py | 4585 +++++++++ .../site-packages/fastapi/background.py | 59 + .../python3.11/site-packages/fastapi/cli.py | 13 + .../site-packages/fastapi/concurrency.py | 39 + .../site-packages/fastapi/datastructures.py | 204 + .../fastapi/dependencies/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 199 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 3383 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 41939 bytes .../fastapi/dependencies/models.py | 37 + .../fastapi/dependencies/utils.py | 980 ++ .../site-packages/fastapi/encoders.py | 343 + .../fastapi/exception_handlers.py | 34 + .../site-packages/fastapi/exceptions.py | 176 + .../site-packages/fastapi/logger.py | 3 + .../fastapi/middleware/__init__.py | 1 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 266 bytes .../__pycache__/cors.cpython-311.pyc | Bin 0 -> 271 bytes .../__pycache__/gzip.cpython-311.pyc | Bin 0 -> 271 bytes .../__pycache__/httpsredirect.cpython-311.pyc | Bin 0 -> 314 bytes .../__pycache__/trustedhost.cpython-311.pyc | Bin 0 -> 308 bytes .../__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 271 bytes .../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 | 1 + .../site-packages/fastapi/openapi/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 194 bytes .../__pycache__/constants.cpython-311.pyc | Bin 0 -> 364 bytes .../openapi/__pycache__/docs.cpython-311.pyc | Bin 0 -> 11442 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 28940 bytes .../openapi/__pycache__/utils.cpython-311.pyc | Bin 0 -> 23300 bytes .../fastapi/openapi/constants.py | 3 + .../site-packages/fastapi/openapi/docs.py | 344 + .../site-packages/fastapi/openapi/models.py | 445 + .../site-packages/fastapi/openapi/utils.py | 569 ++ .../site-packages/fastapi/param_functions.py | 2360 +++++ .../site-packages/fastapi/params.py | 786 ++ .../python3.11/site-packages/fastapi/py.typed | 0 .../site-packages/fastapi/requests.py | 2 + .../site-packages/fastapi/responses.py | 48 + .../site-packages/fastapi/routing.py | 4439 +++++++++ .../fastapi/security/__init__.py | 15 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1072 bytes .../__pycache__/api_key.cpython-311.pyc | Bin 0 -> 10304 bytes .../security/__pycache__/base.cpython-311.pyc | Bin 0 -> 594 bytes .../security/__pycache__/http.cpython-311.pyc | Bin 0 -> 15008 bytes .../__pycache__/oauth2.cpython-311.pyc | Bin 0 -> 20304 bytes .../open_id_connect_url.cpython-311.pyc | Bin 0 -> 3545 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 674 bytes .../site-packages/fastapi/security/api_key.py | 288 + .../site-packages/fastapi/security/base.py | 6 + .../site-packages/fastapi/security/http.py | 423 + .../site-packages/fastapi/security/oauth2.py | 638 ++ .../fastapi/security/open_id_connect_url.py | 84 + .../site-packages/fastapi/security/utils.py | 10 + .../site-packages/fastapi/staticfiles.py | 1 + .../site-packages/fastapi/templating.py | 1 + .../site-packages/fastapi/testclient.py | 1 + .../python3.11/site-packages/fastapi/types.py | 10 + .../python3.11/site-packages/fastapi/utils.py | 220 + .../site-packages/fastapi/websockets.py | 3 + .../h11-0.14.0.dist-info/INSTALLER | 1 + .../h11-0.14.0.dist-info/LICENSE.txt | 22 + .../h11-0.14.0.dist-info/METADATA | 193 + .../site-packages/h11-0.14.0.dist-info/RECORD | 52 + .../site-packages/h11-0.14.0.dist-info/WHEEL | 5 + .../h11-0.14.0.dist-info/top_level.txt | 1 + .../python3.11/site-packages/h11/__init__.py | 62 + .../h11/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1315 bytes .../h11/__pycache__/_abnf.cpython-311.pyc | Bin 0 -> 1820 bytes .../__pycache__/_connection.cpython-311.pyc | Bin 0 -> 24306 bytes .../h11/__pycache__/_events.cpython-311.pyc | Bin 0 -> 15194 bytes .../h11/__pycache__/_headers.cpython-311.pyc | Bin 0 -> 9111 bytes .../h11/__pycache__/_readers.cpython-311.pyc | Bin 0 -> 10788 bytes .../_receivebuffer.cpython-311.pyc | Bin 0 -> 5147 bytes .../h11/__pycache__/_state.cpython-311.pyc | Bin 0 -> 9783 bytes .../h11/__pycache__/_util.cpython-311.pyc | Bin 0 -> 5368 bytes .../h11/__pycache__/_version.cpython-311.pyc | Bin 0 -> 205 bytes .../h11/__pycache__/_writers.cpython-311.pyc | Bin 0 -> 7305 bytes .../lib/python3.11/site-packages/h11/_abnf.py | 132 + .../site-packages/h11/_connection.py | 633 ++ .../python3.11/site-packages/h11/_events.py | 369 + .../python3.11/site-packages/h11/_headers.py | 278 + .../python3.11/site-packages/h11/_readers.py | 247 + .../site-packages/h11/_receivebuffer.py | 153 + .../python3.11/site-packages/h11/_state.py | 367 + .../lib/python3.11/site-packages/h11/_util.py | 135 + .../python3.11/site-packages/h11/_version.py | 16 + .../python3.11/site-packages/h11/_writers.py | 145 + .../lib/python3.11/site-packages/h11/py.typed | 1 + .../site-packages/h11/tests/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 188 bytes .../tests/__pycache__/helpers.cpython-311.pyc | Bin 0 -> 5108 bytes .../test_against_stdlib_http.cpython-311.pyc | Bin 0 -> 8272 bytes .../test_connection.cpython-311.pyc | Bin 0 -> 68024 bytes .../__pycache__/test_events.cpython-311.pyc | Bin 0 -> 6824 bytes .../__pycache__/test_headers.cpython-311.pyc | Bin 0 -> 9601 bytes .../__pycache__/test_helpers.cpython-311.pyc | Bin 0 -> 1524 bytes .../tests/__pycache__/test_io.cpython-311.pyc | Bin 0 -> 25537 bytes .../test_receivebuffer.cpython-311.pyc | Bin 0 -> 4603 bytes .../__pycache__/test_state.cpython-311.pyc | Bin 0 -> 15205 bytes .../__pycache__/test_util.cpython-311.pyc | Bin 0 -> 7811 bytes .../site-packages/h11/tests/data/test-file | 1 + .../site-packages/h11/tests/helpers.py | 101 + .../h11/tests/test_against_stdlib_http.py | 115 + .../h11/tests/test_connection.py | 1122 +++ .../site-packages/h11/tests/test_events.py | 150 + .../site-packages/h11/tests/test_headers.py | 157 + .../site-packages/h11/tests/test_helpers.py | 32 + .../site-packages/h11/tests/test_io.py | 572 ++ .../h11/tests/test_receivebuffer.py | 135 + .../site-packages/h11/tests/test_state.py | 271 + .../site-packages/h11/tests/test_util.py | 112 + .../idna-3.10.dist-info/INSTALLER | 1 + .../idna-3.10.dist-info/LICENSE.md | 31 + .../idna-3.10.dist-info/METADATA | 250 + .../site-packages/idna-3.10.dist-info/RECORD | 22 + .../site-packages/idna-3.10.dist-info/WHEEL | 4 + .../python3.11/site-packages/idna/__init__.py | 45 + .../idna/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1090 bytes .../idna/__pycache__/codec.cpython-311.pyc | Bin 0 -> 5772 bytes .../idna/__pycache__/compat.cpython-311.pyc | Bin 0 -> 1012 bytes .../idna/__pycache__/core.cpython-311.pyc | Bin 0 -> 19259 bytes .../idna/__pycache__/idnadata.cpython-311.pyc | Bin 0 -> 101531 bytes .../__pycache__/intranges.cpython-311.pyc | Bin 0 -> 2970 bytes .../__pycache__/package_data.cpython-311.pyc | Bin 0 -> 206 bytes .../__pycache__/uts46data.cpython-311.pyc | Bin 0 -> 163161 bytes .../python3.11/site-packages/idna/codec.py | 122 + .../python3.11/site-packages/idna/compat.py | 15 + .../lib/python3.11/site-packages/idna/core.py | 437 + .../python3.11/site-packages/idna/idnadata.py | 4243 ++++++++ .../site-packages/idna/intranges.py | 57 + .../site-packages/idna/package_data.py | 1 + .../python3.11/site-packages/idna/py.typed | 0 .../site-packages/idna/uts46data.py | 8681 +++++++++++++++++ .../jinja2-3.1.6.dist-info/INSTALLER | 1 + .../jinja2-3.1.6.dist-info/METADATA | 84 + .../jinja2-3.1.6.dist-info/RECORD | 58 + .../jinja2-3.1.6.dist-info/REQUESTED | 0 .../jinja2-3.1.6.dist-info/WHEEL | 4 + .../jinja2-3.1.6.dist-info/entry_points.txt | 3 + .../licenses/LICENSE.txt | 28 + .../site-packages/jinja2/__init__.py | 38 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2118 bytes .../__pycache__/_identifier.cpython-311.pyc | Bin 0 -> 2134 bytes .../__pycache__/async_utils.cpython-311.pyc | Bin 0 -> 5594 bytes .../__pycache__/bccache.cpython-311.pyc | Bin 0 -> 20916 bytes .../__pycache__/compiler.cpython-311.pyc | Bin 0 -> 112438 bytes .../__pycache__/constants.cpython-311.pyc | Bin 0 -> 1553 bytes .../jinja2/__pycache__/debug.cpython-311.pyc | Bin 0 -> 6713 bytes .../__pycache__/defaults.cpython-311.pyc | Bin 0 -> 1719 bytes .../__pycache__/environment.cpython-311.pyc | Bin 0 -> 80576 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8604 bytes .../jinja2/__pycache__/ext.cpython-311.pyc | Bin 0 -> 43380 bytes .../__pycache__/filters.cpython-311.pyc | Bin 0 -> 77638 bytes .../__pycache__/idtracking.cpython-311.pyc | Bin 0 -> 19508 bytes .../jinja2/__pycache__/lexer.cpython-311.pyc | Bin 0 -> 35661 bytes .../__pycache__/loaders.cpython-311.pyc | Bin 0 -> 34394 bytes .../jinja2/__pycache__/meta.cpython-311.pyc | Bin 0 -> 5698 bytes .../__pycache__/nativetypes.cpython-311.pyc | Bin 0 -> 7960 bytes .../jinja2/__pycache__/nodes.cpython-311.pyc | Bin 0 -> 64479 bytes .../__pycache__/optimizer.cpython-311.pyc | Bin 0 -> 2849 bytes .../jinja2/__pycache__/parser.cpython-311.pyc | Bin 0 -> 60025 bytes .../__pycache__/runtime.cpython-311.pyc | Bin 0 -> 51112 bytes .../__pycache__/sandbox.cpython-311.pyc | Bin 0 -> 19220 bytes .../jinja2/__pycache__/tests.cpython-311.pyc | Bin 0 -> 9269 bytes .../jinja2/__pycache__/utils.cpython-311.pyc | Bin 0 -> 37556 bytes .../__pycache__/visitor.cpython-311.pyc | Bin 0 -> 5697 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 99 + .../site-packages/jinja2/bccache.py | 408 + .../site-packages/jinja2/compiler.py | 1998 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.11/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1672 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../python3.11/site-packages/jinja2/ext.py | 870 ++ .../site-packages/jinja2/filters.py | 1873 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.11/site-packages/jinja2/lexer.py | 868 ++ .../site-packages/jinja2/loaders.py | 693 ++ .../python3.11/site-packages/jinja2/meta.py | 112 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.11/site-packages/jinja2/nodes.py | 1206 +++ .../site-packages/jinja2/optimizer.py | 48 + .../python3.11/site-packages/jinja2/parser.py | 1049 ++ .../python3.11/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1062 ++ .../site-packages/jinja2/sandbox.py | 436 + .../python3.11/site-packages/jinja2/tests.py | 256 + .../python3.11/site-packages/jinja2/utils.py | 766 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 395 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 25735 bytes .../__pycache__/_native.cpython-311.pyc | Bin 0 -> 686 bytes .../site-packages/markupsafe/_native.py | 8 + .../site-packages/markupsafe/_speedups.c | 204 + .../_speedups.cpython-311-x86_64-linux-gnu.so | Bin 0 -> 43456 bytes .../site-packages/markupsafe/_speedups.pyi | 1 + .../site-packages/markupsafe/py.typed | 0 .../pip-23.0.1.dist-info/INSTALLER | 1 + .../pip-23.0.1.dist-info/LICENSE.txt | 20 + .../pip-23.0.1.dist-info/METADATA | 88 + .../site-packages/pip-23.0.1.dist-info/RECORD | 996 ++ .../pip-23.0.1.dist-info/REQUESTED | 0 .../site-packages/pip-23.0.1.dist-info/WHEEL | 5 + .../pip-23.0.1.dist-info/entry_points.txt | 4 + .../pip-23.0.1.dist-info/top_level.txt | 1 + .../python3.11/site-packages/pip/__init__.py | 13 + .../python3.11/site-packages/pip/__main__.py | 31 + .../site-packages/pip/__pip-runner__.py | 50 + .../pip/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 771 bytes .../pip/__pycache__/__main__.cpython-311.pyc | Bin 0 -> 1080 bytes .../__pip-runner__.cpython-311.pyc | Bin 0 -> 2508 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 954 bytes .../__pycache__/build_env.cpython-311.pyc | Bin 0 -> 16074 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 14699 bytes .../__pycache__/configuration.cpython-311.pyc | Bin 0 -> 19230 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 38359 bytes .../__pycache__/main.cpython-311.pyc | Bin 0 -> 754 bytes .../__pycache__/pyproject.cpython-311.pyc | Bin 0 -> 5522 bytes .../self_outdated_check.cpython-311.pyc | Bin 0 -> 11324 bytes .../__pycache__/wheel_builder.cpython-311.pyc | Bin 0 -> 15994 bytes .../site-packages/pip/_internal/build_env.py | 311 + .../site-packages/pip/_internal/cache.py | 293 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 289 bytes .../autocompletion.cpython-311.pyc | Bin 0 -> 10079 bytes .../__pycache__/base_command.cpython-311.pyc | Bin 0 -> 11077 bytes .../__pycache__/cmdoptions.cpython-311.pyc | Bin 0 -> 32976 bytes .../command_context.cpython-311.pyc | Bin 0 -> 2111 bytes .../cli/__pycache__/main.cpython-311.pyc | Bin 0 -> 2366 bytes .../__pycache__/main_parser.cpython-311.pyc | Bin 0 -> 5525 bytes .../cli/__pycache__/parser.cpython-311.pyc | Bin 0 -> 17026 bytes .../__pycache__/progress_bars.cpython-311.pyc | Bin 0 -> 3173 bytes .../__pycache__/req_command.cpython-311.pyc | Bin 0 -> 20138 bytes .../cli/__pycache__/spinners.cpython-311.pyc | Bin 0 -> 8838 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 0 -> 377 bytes .../pip/_internal/cli/autocompletion.py | 171 + .../pip/_internal/cli/base_command.py | 216 + .../pip/_internal/cli/cmdoptions.py | 1055 ++ .../pip/_internal/cli/command_context.py | 27 + .../site-packages/pip/_internal/cli/main.py | 70 + .../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 | 502 + .../pip/_internal/cli/spinners.py | 159 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 132 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 4457 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 10556 bytes .../__pycache__/check.cpython-311.pyc | Bin 0 -> 2307 bytes .../__pycache__/completion.cpython-311.pyc | Bin 0 -> 5469 bytes .../__pycache__/configuration.cpython-311.pyc | Bin 0 -> 14898 bytes .../__pycache__/debug.cpython-311.pyc | Bin 0 -> 12006 bytes .../__pycache__/download.cpython-311.pyc | Bin 0 -> 7813 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 0 -> 4158 bytes .../commands/__pycache__/hash.cpython-311.pyc | Bin 0 -> 3359 bytes .../commands/__pycache__/help.cpython-311.pyc | Bin 0 -> 1971 bytes .../__pycache__/index.cpython-311.pyc | Bin 0 -> 7794 bytes .../__pycache__/inspect.cpython-311.pyc | Bin 0 -> 4447 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 35376 bytes .../commands/__pycache__/list.cpython-311.pyc | Bin 0 -> 17508 bytes .../__pycache__/search.cpython-311.pyc | Bin 0 -> 8953 bytes .../commands/__pycache__/show.cpython-311.pyc | Bin 0 -> 11296 bytes .../__pycache__/uninstall.cpython-311.pyc | Bin 0 -> 5147 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 9953 bytes .../pip/_internal/commands/cache.py | 223 + .../pip/_internal/commands/check.py | 53 + .../pip/_internal/commands/completion.py | 126 + .../pip/_internal/commands/configuration.py | 282 + .../pip/_internal/commands/debug.py | 199 + .../pip/_internal/commands/download.py | 149 + .../pip/_internal/commands/freeze.py | 97 + .../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 | 873 ++ .../pip/_internal/commands/list.py | 367 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 189 + .../pip/_internal/commands/uninstall.py | 113 + .../pip/_internal/commands/wheel.py | 203 + .../pip/_internal/configuration.py | 374 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1039 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 2411 bytes .../__pycache__/installed.cpython-311.pyc | Bin 0 -> 1548 bytes .../__pycache__/sdist.cpython-311.pyc | Bin 0 -> 8950 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 2142 bytes .../pip/_internal/distributions/base.py | 39 + .../pip/_internal/distributions/installed.py | 23 + .../pip/_internal/distributions/sdist.py | 150 + .../pip/_internal/distributions/wheel.py | 34 + .../site-packages/pip/_internal/exceptions.py | 747 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 243 bytes .../__pycache__/collector.cpython-311.pyc | Bin 0 -> 24549 bytes .../package_finder.cpython-311.pyc | Bin 0 -> 44221 bytes .../index/__pycache__/sources.cpython-311.pyc | Bin 0 -> 11025 bytes .../pip/_internal/index/collector.py | 505 + .../pip/_internal/index/package_finder.py | 1029 ++ .../pip/_internal/index/sources.py | 224 + .../pip/_internal/locations/__init__.py | 467 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 18181 bytes .../__pycache__/_distutils.cpython-311.pyc | Bin 0 -> 7590 bytes .../__pycache__/_sysconfig.cpython-311.pyc | Bin 0 -> 8885 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 4006 bytes .../pip/_internal/locations/_distutils.py | 173 + .../pip/_internal/locations/_sysconfig.py | 213 + .../pip/_internal/locations/base.py | 81 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 127 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6414 bytes .../__pycache__/_json.cpython-311.pyc | Bin 0 -> 3568 bytes .../metadata/__pycache__/base.cpython-311.pyc | Bin 0 -> 38013 bytes .../__pycache__/pkg_resources.cpython-311.pyc | Bin 0 -> 16861 bytes .../pip/_internal/metadata/_json.py | 84 + .../pip/_internal/metadata/base.py | 688 ++ .../_internal/metadata/importlib/__init__.py | 4 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 360 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 3567 bytes .../__pycache__/_dists.cpython-311.pyc | Bin 0 -> 14583 bytes .../__pycache__/_envs.cpython-311.pyc | Bin 0 -> 12421 bytes .../_internal/metadata/importlib/_compat.py | 55 + .../_internal/metadata/importlib/_dists.py | 224 + .../pip/_internal/metadata/importlib/_envs.py | 188 + .../pip/_internal/metadata/pkg_resources.py | 270 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 277 bytes .../__pycache__/candidate.cpython-311.pyc | Bin 0 -> 2096 bytes .../__pycache__/direct_url.cpython-311.pyc | Bin 0 -> 12259 bytes .../format_control.cpython-311.pyc | Bin 0 -> 4660 bytes .../models/__pycache__/index.cpython-311.pyc | Bin 0 -> 1902 bytes .../installation_report.cpython-311.pyc | Bin 0 -> 2616 bytes .../models/__pycache__/link.cpython-311.pyc | Bin 0 -> 26448 bytes .../models/__pycache__/scheme.cpython-311.pyc | Bin 0 -> 1268 bytes .../__pycache__/search_scope.cpython-311.pyc | Bin 0 -> 5831 bytes .../selection_prefs.cpython-311.pyc | Bin 0 -> 1999 bytes .../__pycache__/target_python.cpython-311.pyc | Bin 0 -> 4761 bytes .../models/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 6424 bytes .../pip/_internal/models/candidate.py | 34 + .../pip/_internal/models/direct_url.py | 228 + .../pip/_internal/models/format_control.py | 80 + .../pip/_internal/models/index.py | 28 + .../_internal/models/installation_report.py | 53 + .../pip/_internal/models/link.py | 524 + .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 133 + .../pip/_internal/models/selection_prefs.py | 51 + .../pip/_internal/models/target_python.py | 110 + .../pip/_internal/models/wheel.py | 92 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 265 bytes .../network/__pycache__/auth.cpython-311.pyc | Bin 0 -> 19069 bytes .../network/__pycache__/cache.cpython-311.pyc | Bin 0 -> 5188 bytes .../__pycache__/download.cpython-311.pyc | Bin 0 -> 9580 bytes .../__pycache__/lazy_wheel.cpython-311.pyc | Bin 0 -> 13026 bytes .../__pycache__/session.cpython-311.pyc | Bin 0 -> 21293 bytes .../network/__pycache__/utils.cpython-311.pyc | Bin 0 -> 2414 bytes .../__pycache__/xmlrpc.cpython-311.pyc | Bin 0 -> 3193 bytes .../pip/_internal/network/auth.py | 446 + .../pip/_internal/network/cache.py | 69 + .../pip/_internal/network/download.py | 186 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 518 + .../pip/_internal/network/utils.py | 96 + .../pip/_internal/network/xmlrpc.py | 60 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 203 bytes .../__pycache__/check.cpython-311.pyc | Bin 0 -> 6636 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 0 -> 11599 bytes .../__pycache__/prepare.cpython-311.pyc | Bin 0 -> 26383 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 209 bytes .../__pycache__/build_tracker.cpython-311.pyc | Bin 0 -> 8132 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 0 -> 2280 bytes .../metadata_editable.cpython-311.pyc | Bin 0 -> 2316 bytes .../metadata_legacy.cpython-311.pyc | Bin 0 -> 3716 bytes .../build/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 1946 bytes .../wheel_editable.cpython-311.pyc | Bin 0 -> 2390 bytes .../__pycache__/wheel_legacy.cpython-311.pyc | Bin 0 -> 4497 bytes .../operations/build/build_tracker.py | 124 + .../_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 | 149 + .../pip/_internal/operations/freeze.py | 254 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 277 bytes .../editable_legacy.cpython-311.pyc | Bin 0 -> 2273 bytes .../__pycache__/legacy.cpython-311.pyc | Bin 0 -> 6113 bytes .../install/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 39999 bytes .../operations/install/editable_legacy.py | 47 + .../_internal/operations/install/legacy.py | 120 + .../pip/_internal/operations/install/wheel.py | 738 ++ .../pip/_internal/operations/prepare.py | 667 ++ .../site-packages/pip/_internal/pyproject.py | 174 + .../pip/_internal/req/__init__.py | 94 + .../req/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 4449 bytes .../__pycache__/constructors.cpython-311.pyc | Bin 0 -> 20708 bytes .../req/__pycache__/req_file.cpython-311.pyc | Bin 0 -> 22437 bytes .../__pycache__/req_install.cpython-311.pyc | Bin 0 -> 40349 bytes .../req/__pycache__/req_set.cpython-311.pyc | Bin 0 -> 6005 bytes .../__pycache__/req_uninstall.cpython-311.pyc | Bin 0 -> 37003 bytes .../pip/_internal/req/constructors.py | 501 + .../pip/_internal/req/req_file.py | 544 ++ .../pip/_internal/req/req_install.py | 946 ++ .../pip/_internal/req/req_set.py | 82 + .../pip/_internal/req/req_uninstall.py | 640 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 203 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 1374 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 210 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 0 -> 23796 bytes .../_internal/resolution/legacy/resolver.py | 600 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 214 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 9627 bytes .../__pycache__/candidates.cpython-311.pyc | Bin 0 -> 28837 bytes .../__pycache__/factory.cpython-311.pyc | Bin 0 -> 31981 bytes .../found_candidates.cpython-311.pyc | Bin 0 -> 6762 bytes .../__pycache__/provider.cpython-311.pyc | Bin 0 -> 11056 bytes .../__pycache__/reporter.cpython-311.pyc | Bin 0 -> 4659 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 11124 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 0 -> 12311 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 556 ++ .../resolution/resolvelib/factory.py | 731 ++ .../resolution/resolvelib/found_candidates.py | 155 + .../resolution/resolvelib/provider.py | 248 + .../resolution/resolvelib/reporter.py | 68 + .../resolution/resolvelib/requirements.py | 166 + .../resolution/resolvelib/resolver.py | 296 + .../pip/_internal/self_outdated_check.py | 242 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 198 bytes .../utils/__pycache__/_log.cpython-311.pyc | Bin 0 -> 2019 bytes .../utils/__pycache__/appdirs.cpython-311.pyc | Bin 0 -> 2557 bytes .../utils/__pycache__/compat.cpython-311.pyc | Bin 0 -> 2265 bytes .../compatibility_tags.cpython-311.pyc | Bin 0 -> 6757 bytes .../__pycache__/datetime.cpython-311.pyc | Bin 0 -> 715 bytes .../__pycache__/deprecation.cpython-311.pyc | Bin 0 -> 7088 bytes .../direct_url_helpers.cpython-311.pyc | Bin 0 -> 3721 bytes .../distutils_args.cpython-311.pyc | Bin 0 -> 1465 bytes .../__pycache__/egg_link.cpython-311.pyc | Bin 0 -> 3236 bytes .../__pycache__/encoding.cpython-311.pyc | Bin 0 -> 2321 bytes .../__pycache__/entrypoints.cpython-311.pyc | Bin 0 -> 4243 bytes .../__pycache__/filesystem.cpython-311.pyc | Bin 0 -> 8228 bytes .../__pycache__/filetypes.cpython-311.pyc | Bin 0 -> 1314 bytes .../utils/__pycache__/glibc.cpython-311.pyc | Bin 0 -> 2557 bytes .../utils/__pycache__/hashes.cpython-311.pyc | Bin 0 -> 8335 bytes .../inject_securetransport.cpython-311.pyc | Bin 0 -> 1332 bytes .../utils/__pycache__/logging.cpython-311.pyc | Bin 0 -> 15457 bytes .../utils/__pycache__/misc.cpython-311.pyc | Bin 0 -> 37699 bytes .../utils/__pycache__/models.cpython-311.pyc | Bin 0 -> 2938 bytes .../__pycache__/packaging.cpython-311.pyc | Bin 0 -> 2805 bytes .../setuptools_build.cpython-311.pyc | Bin 0 -> 6102 bytes .../__pycache__/subprocess.cpython-311.pyc | Bin 0 -> 9892 bytes .../__pycache__/temp_dir.cpython-311.pyc | Bin 0 -> 11419 bytes .../__pycache__/unpacking.cpython-311.pyc | Bin 0 -> 12894 bytes .../utils/__pycache__/urls.cpython-311.pyc | Bin 0 -> 2691 bytes .../__pycache__/virtualenv.cpython-311.pyc | Bin 0 -> 4938 bytes .../utils/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 7108 bytes .../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 | 188 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/distutils_args.py | 43 + .../pip/_internal/utils/egg_link.py | 72 + .../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 | 144 + .../_internal/utils/inject_securetransport.py | 35 + .../pip/_internal/utils/logging.py | 348 + .../site-packages/pip/_internal/utils/misc.py | 763 ++ .../pip/_internal/utils/models.py | 39 + .../pip/_internal/utils/packaging.py | 57 + .../pip/_internal/utils/setuptools_build.py | 195 + .../pip/_internal/utils/subprocess.py | 260 + .../pip/_internal/utils/temp_dir.py | 246 + .../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 | 136 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 633 bytes .../vcs/__pycache__/bazaar.cpython-311.pyc | Bin 0 -> 5858 bytes .../vcs/__pycache__/git.cpython-311.pyc | Bin 0 -> 21522 bytes .../vcs/__pycache__/mercurial.cpython-311.pyc | Bin 0 -> 8704 bytes .../__pycache__/subversion.cpython-311.pyc | Bin 0 -> 14601 bytes .../versioncontrol.cpython-311.pyc | Bin 0 -> 31870 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 | 382 + .../site-packages/pip/_vendor/__init__.py | 120 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 5611 bytes .../_vendor/__pycache__/six.cpython-311.pyc | Bin 0 -> 46413 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 97443 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 840 bytes .../__pycache__/_cmd.cpython-311.pyc | Bin 0 -> 2695 bytes .../__pycache__/adapter.cpython-311.pyc | Bin 0 -> 5502 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 3776 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 1133 bytes .../__pycache__/controller.cpython-311.pyc | Bin 0 -> 16448 bytes .../__pycache__/filewrapper.cpython-311.pyc | Bin 0 -> 4235 bytes .../__pycache__/heuristics.cpython-311.pyc | Bin 0 -> 6680 bytes .../__pycache__/serialize.cpython-311.pyc | Bin 0 -> 8395 bytes .../__pycache__/wrapper.cpython-311.pyc | Bin 0 -> 961 bytes .../pip/_vendor/cachecontrol/_cmd.py | 61 + .../pip/_vendor/cachecontrol/adapter.py | 137 + .../pip/_vendor/cachecontrol/cache.py | 65 + .../_vendor/cachecontrol/caches/__init__.py | 9 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 415 bytes .../__pycache__/file_cache.cpython-311.pyc | Bin 0 -> 8398 bytes .../__pycache__/redis_cache.cpython-311.pyc | Bin 0 -> 2495 bytes .../_vendor/cachecontrol/caches/file_cache.py | 188 + .../cachecontrol/caches/redis_cache.py | 39 + .../pip/_vendor/cachecontrol/compat.py | 32 + .../pip/_vendor/cachecontrol/controller.py | 439 + .../pip/_vendor/cachecontrol/filewrapper.py | 111 + .../pip/_vendor/cachecontrol/heuristics.py | 139 + .../pip/_vendor/cachecontrol/serialize.py | 190 + .../pip/_vendor/cachecontrol/wrapper.py | 33 + .../pip/_vendor/certifi/__init__.py | 4 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 340 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 741 bytes .../certifi/__pycache__/core.cpython-311.pyc | Bin 0 -> 3983 bytes .../pip/_vendor/certifi/cacert.pem | 4527 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 119 + .../pip/_vendor/chardet/__init__.py | 115 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 5072 bytes .../__pycache__/big5freq.cpython-311.pyc | Bin 0 -> 27202 bytes .../__pycache__/big5prober.cpython-311.pyc | Bin 0 -> 1677 bytes .../chardistribution.cpython-311.pyc | Bin 0 -> 11269 bytes .../charsetgroupprober.cpython-311.pyc | Bin 0 -> 4299 bytes .../__pycache__/charsetprober.cpython-311.pyc | Bin 0 -> 5545 bytes .../codingstatemachine.cpython-311.pyc | Bin 0 -> 3996 bytes .../codingstatemachinedict.cpython-311.pyc | Bin 0 -> 952 bytes .../__pycache__/cp949prober.cpython-311.pyc | Bin 0 -> 1686 bytes .../chardet/__pycache__/enums.cpython-311.pyc | Bin 0 -> 3387 bytes .../__pycache__/escprober.cpython-311.pyc | Bin 0 -> 4903 bytes .../chardet/__pycache__/escsm.cpython-311.pyc | Bin 0 -> 12642 bytes .../__pycache__/eucjpprober.cpython-311.pyc | Bin 0 -> 4729 bytes .../__pycache__/euckrfreq.cpython-311.pyc | Bin 0 -> 12085 bytes .../__pycache__/euckrprober.cpython-311.pyc | Bin 0 -> 1678 bytes .../__pycache__/euctwfreq.cpython-311.pyc | Bin 0 -> 27207 bytes .../__pycache__/euctwprober.cpython-311.pyc | Bin 0 -> 1678 bytes .../__pycache__/gb2312freq.cpython-311.pyc | Bin 0 -> 19129 bytes .../__pycache__/gb2312prober.cpython-311.pyc | Bin 0 -> 1693 bytes .../__pycache__/hebrewprober.cpython-311.pyc | Bin 0 -> 5682 bytes .../__pycache__/jisfreq.cpython-311.pyc | Bin 0 -> 22158 bytes .../__pycache__/johabfreq.cpython-311.pyc | Bin 0 -> 84662 bytes .../__pycache__/johabprober.cpython-311.pyc | Bin 0 -> 1684 bytes .../__pycache__/jpcntx.cpython-311.pyc | Bin 0 -> 40166 bytes .../langbulgarianmodel.cpython-311.pyc | Bin 0 -> 85836 bytes .../langgreekmodel.cpython-311.pyc | Bin 0 -> 79258 bytes .../langhebrewmodel.cpython-311.pyc | Bin 0 -> 80020 bytes .../langhungarianmodel.cpython-311.pyc | Bin 0 -> 85790 bytes .../langrussianmodel.cpython-311.pyc | Bin 0 -> 108737 bytes .../__pycache__/langthaimodel.cpython-311.pyc | Bin 0 -> 80198 bytes .../langturkishmodel.cpython-311.pyc | Bin 0 -> 80037 bytes .../__pycache__/latin1prober.cpython-311.pyc | Bin 0 -> 7333 bytes .../macromanprober.cpython-311.pyc | Bin 0 -> 7500 bytes .../mbcharsetprober.cpython-311.pyc | Bin 0 -> 4121 bytes .../mbcsgroupprober.cpython-311.pyc | Bin 0 -> 1991 bytes .../__pycache__/mbcssm.cpython-311.pyc | Bin 0 -> 31731 bytes .../__pycache__/resultdict.cpython-311.pyc | Bin 0 -> 770 bytes .../sbcharsetprober.cpython-311.pyc | Bin 0 -> 6396 bytes .../sbcsgroupprober.cpython-311.pyc | Bin 0 -> 2941 bytes .../__pycache__/sjisprober.cpython-311.pyc | Bin 0 -> 4834 bytes .../universaldetector.cpython-311.pyc | Bin 0 -> 12462 bytes .../__pycache__/utf1632prober.cpython-311.pyc | Bin 0 -> 10582 bytes .../__pycache__/utf8prober.cpython-311.pyc | Bin 0 -> 3469 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 505 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-311.pyc | Bin 0 -> 202 bytes .../__pycache__/chardetect.cpython-311.pyc | Bin 0 -> 4341 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-311.pyc | Bin 0 -> 207 bytes .../__pycache__/languages.cpython-311.pyc | Bin 0 -> 10807 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-311.pyc | Bin 0 -> 574 bytes .../colorama/__pycache__/ansi.cpython-311.pyc | Bin 0 -> 4572 bytes .../__pycache__/ansitowin32.cpython-311.pyc | Bin 0 -> 16218 bytes .../__pycache__/initialise.cpython-311.pyc | Bin 0 -> 3935 bytes .../__pycache__/win32.cpython-311.pyc | Bin 0 -> 7923 bytes .../__pycache__/winterm.cpython-311.pyc | Bin 0 -> 9149 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-311.pyc | Bin 0 -> 205 bytes .../__pycache__/ansi_test.cpython-311.pyc | Bin 0 -> 5850 bytes .../ansitowin32_test.cpython-311.pyc | Bin 0 -> 21517 bytes .../initialise_test.cpython-311.pyc | Bin 0 -> 14144 bytes .../__pycache__/isatty_test.cpython-311.pyc | Bin 0 -> 6709 bytes .../tests/__pycache__/utils.cpython-311.pyc | Bin 0 -> 2884 bytes .../__pycache__/winterm_test.cpython-311.pyc | Bin 0 -> 7237 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 | 23 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1443 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 52309 bytes .../__pycache__/database.cpython-311.pyc | Bin 0 -> 72097 bytes .../distlib/__pycache__/index.cpython-311.pyc | Bin 0 -> 26686 bytes .../__pycache__/locators.cpython-311.pyc | Bin 0 -> 65862 bytes .../__pycache__/manifest.cpython-311.pyc | Bin 0 -> 17029 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 8165 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 0 -> 47113 bytes .../__pycache__/resources.cpython-311.pyc | Bin 0 -> 18992 bytes .../__pycache__/scripts.cpython-311.pyc | Bin 0 -> 21268 bytes .../distlib/__pycache__/util.cpython-311.pyc | Bin 0 -> 97447 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 34574 bytes .../distlib/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 60378 bytes .../pip/_vendor/distlib/compat.py | 1116 +++ .../pip/_vendor/distlib/database.py | 1350 +++ .../pip/_vendor/distlib/index.py | 508 + .../pip/_vendor/distlib/locators.py | 1300 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 152 + .../pip/_vendor/distlib/metadata.py | 1076 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 437 + .../site-packages/pip/_vendor/distlib/util.py | 1932 ++++ .../pip/_vendor/distlib/version.py | 739 ++ .../pip/_vendor/distlib/wheel.py | 1082 ++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1196 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 330 bytes .../distro/__pycache__/distro.cpython-311.pyc | Bin 0 -> 57729 bytes .../pip/_vendor/distro/distro.py | 1399 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1097 bytes .../idna/__pycache__/codec.cpython-311.pyc | Bin 0 -> 5388 bytes .../idna/__pycache__/compat.cpython-311.pyc | Bin 0 -> 1014 bytes .../idna/__pycache__/core.cpython-311.pyc | Bin 0 -> 19449 bytes .../idna/__pycache__/idnadata.cpython-311.pyc | Bin 0 -> 38973 bytes .../__pycache__/intranges.cpython-311.pyc | Bin 0 -> 2982 bytes .../__pycache__/package_data.cpython-311.pyc | Bin 0 -> 217 bytes .../__pycache__/uts46data.cpython-311.pyc | Bin 0 -> 163197 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 | 2151 ++++ .../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-311.pyc | Bin 0 -> 2076 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 2377 bytes .../msgpack/__pycache__/ext.cpython-311.pyc | Bin 0 -> 9163 bytes .../__pycache__/fallback.cpython-311.pyc | Bin 0 -> 47190 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-311.pyc | Bin 0 -> 641 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 562 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13228 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 7996 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3684 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16524 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7639 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34362 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21347 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6682 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21874 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 | 3296 +++++++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 158230 bytes .../__pycache__/py31compat.cpython-311.pyc | Bin 0 -> 983 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/platformdirs/__init__.py | 342 + .../pip/_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 12929 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 2126 bytes .../__pycache__/android.cpython-311.pyc | Bin 0 -> 6356 bytes .../__pycache__/api.cpython-311.pyc | Bin 0 -> 7183 bytes .../__pycache__/macos.cpython-311.pyc | Bin 0 -> 4593 bytes .../__pycache__/unix.cpython-311.pyc | Bin 0 -> 11025 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 312 bytes .../__pycache__/windows.cpython-311.pyc | Bin 0 -> 9961 bytes .../pip/_vendor/platformdirs/android.py | 120 + .../pip/_vendor/platformdirs/api.py | 156 + .../pip/_vendor/platformdirs/macos.py | 64 + .../pip/_vendor/platformdirs/unix.py | 181 + .../pip/_vendor/platformdirs/version.py | 4 + .../pip/_vendor/platformdirs/windows.py | 184 + .../pip/_vendor/pygments/__init__.py | 82 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3844 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 780 bytes .../__pycache__/cmdline.cpython-311.pyc | Bin 0 -> 30291 bytes .../__pycache__/console.cpython-311.pyc | Bin 0 -> 3043 bytes .../__pycache__/filter.cpython-311.pyc | Bin 0 -> 3504 bytes .../__pycache__/formatter.cpython-311.pyc | Bin 0 -> 3870 bytes .../__pycache__/lexer.cpython-311.pyc | Bin 0 -> 40398 bytes .../__pycache__/modeline.cpython-311.pyc | Bin 0 -> 1723 bytes .../__pycache__/plugin.cpython-311.pyc | Bin 0 -> 3736 bytes .../__pycache__/regexopt.cpython-311.pyc | Bin 0 -> 5030 bytes .../__pycache__/scanner.cpython-311.pyc | Bin 0 -> 4885 bytes .../__pycache__/sphinxext.cpython-311.pyc | Bin 0 -> 8316 bytes .../__pycache__/style.cpython-311.pyc | Bin 0 -> 7424 bytes .../__pycache__/token.cpython-311.pyc | Bin 0 -> 7464 bytes .../__pycache__/unistring.cpython-311.pyc | Bin 0 -> 33798 bytes .../pygments/__pycache__/util.cpython-311.pyc | Bin 0 -> 14591 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-311.pyc | Bin 0 -> 40104 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 143 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6870 bytes .../__pycache__/_mapping.cpython-311.pyc | Bin 0 -> 4152 bytes .../__pycache__/bbcode.cpython-311.pyc | Bin 0 -> 4478 bytes .../__pycache__/groff.cpython-311.pyc | Bin 0 -> 7811 bytes .../__pycache__/html.cpython-311.pyc | Bin 0 -> 42596 bytes .../__pycache__/img.cpython-311.pyc | Bin 0 -> 28568 bytes .../__pycache__/irc.cpython-311.pyc | Bin 0 -> 7671 bytes .../__pycache__/latex.cpython-311.pyc | Bin 0 -> 21804 bytes .../__pycache__/other.cpython-311.pyc | Bin 0 -> 7632 bytes .../__pycache__/pangomarkup.cpython-311.pyc | Bin 0 -> 3176 bytes .../__pycache__/rtf.cpython-311.pyc | Bin 0 -> 6843 bytes .../__pycache__/svg.cpython-311.pyc | Bin 0 -> 9663 bytes .../__pycache__/terminal.cpython-311.pyc | Bin 0 -> 6042 bytes .../__pycache__/terminal256.cpython-311.pyc | Bin 0 -> 16408 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 | 179 + .../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 | 882 ++ .../pip/_vendor/pygments/lexers/__init__.py | 335 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 15147 bytes .../__pycache__/_mapping.cpython-311.pyc | Bin 0 -> 62778 bytes .../lexers/__pycache__/python.cpython-311.pyc | Bin 0 -> 43979 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 541 + .../pip/_vendor/pygments/lexers/python.py | 1204 +++ .../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 | 155 + .../pip/_vendor/pygments/style.py | 197 + .../pip/_vendor/pygments/styles/__init__.py | 97 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 4457 bytes .../pip/_vendor/pygments/token.py | 213 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 308 + .../pip/_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 8347 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8461 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14783 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277669 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12925 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53626 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36309 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19505 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15363 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14262 bytes .../pip/_vendor/pyparsing/actions.py | 207 + .../pip/_vendor/pyparsing/common.py | 424 + .../pip/_vendor/pyparsing/core.py | 5814 +++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 642 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 28028 bytes .../pip/_vendor/pyparsing/exceptions.py | 267 + .../pip/_vendor/pyparsing/helpers.py | 1088 +++ .../pip/_vendor/pyparsing/results.py | 760 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 352 + .../pip/_vendor/pyparsing/util.py | 235 + .../pip/_vendor/pyproject_hooks/__init__.py | 23 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 705 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 403 bytes .../__pycache__/_impl.cpython-311.pyc | Bin 0 -> 16669 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-311.pyc | Bin 0 -> 1165 bytes .../__pycache__/_in_process.cpython-311.pyc | Bin 0 -> 16487 bytes .../_in_process/_in_process.py | 353 + .../pip/_vendor/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6449 bytes .../__pycache__/__version__.cpython-311.pyc | Bin 0 -> 586 bytes .../_internal_utils.cpython-311.pyc | Bin 0 -> 2083 bytes .../__pycache__/adapters.cpython-311.pyc | Bin 0 -> 24886 bytes .../requests/__pycache__/api.cpython-311.pyc | Bin 0 -> 7431 bytes .../requests/__pycache__/auth.cpython-311.pyc | Bin 0 -> 14630 bytes .../__pycache__/certs.cpython-311.pyc | Bin 0 -> 982 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 1808 bytes .../__pycache__/cookies.cpython-311.pyc | Bin 0 -> 27110 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8525 bytes .../requests/__pycache__/help.cpython-311.pyc | Bin 0 -> 4520 bytes .../__pycache__/hooks.cpython-311.pyc | Bin 0 -> 1250 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 38781 bytes .../__pycache__/packages.cpython-311.pyc | Bin 0 -> 830 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 0 -> 29619 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 0 -> 6237 bytes .../__pycache__/structures.cpython-311.pyc | Bin 0 -> 6222 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 40136 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 48 + .../pip/_vendor/requests/adapters.py | 584 ++ .../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 | 831 ++ .../pip/_vendor/requests/status_codes.py | 128 + .../pip/_vendor/requests/structures.py | 99 + .../pip/_vendor/requests/utils.py | 1086 +++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 753 bytes .../__pycache__/providers.cpython-311.pyc | Bin 0 -> 7072 bytes .../__pycache__/reporters.cpython-311.pyc | Bin 0 -> 2802 bytes .../__pycache__/resolvers.cpython-311.pyc | Bin 0 -> 25248 bytes .../__pycache__/structs.cpython-311.pyc | Bin 0 -> 11330 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 208 bytes .../collections_abc.cpython-311.pyc | Bin 0 -> 483 bytes .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 133 + .../pip/_vendor/resolvelib/reporters.py | 43 + .../pip/_vendor/resolvelib/resolvers.py | 482 + .../pip/_vendor/resolvelib/structs.py | 165 + .../pip/_vendor/rich/__init__.py | 177 + .../pip/_vendor/rich/__main__.py | 274 + .../rich/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 7496 bytes .../rich/__pycache__/__main__.cpython-311.pyc | Bin 0 -> 11574 bytes .../__pycache__/_cell_widths.cpython-311.pyc | Bin 0 -> 7835 bytes .../__pycache__/_emoji_codes.cpython-311.pyc | Bin 0 -> 208522 bytes .../_emoji_replace.cpython-311.pyc | Bin 0 -> 1934 bytes .../_export_format.cpython-311.pyc | Bin 0 -> 2339 bytes .../__pycache__/_extension.cpython-311.pyc | Bin 0 -> 635 bytes .../rich/__pycache__/_inspect.cpython-311.pyc | Bin 0 -> 14187 bytes .../__pycache__/_log_render.cpython-311.pyc | Bin 0 -> 4769 bytes .../rich/__pycache__/_loop.cpython-311.pyc | Bin 0 -> 2115 bytes .../__pycache__/_null_file.cpython-311.pyc | Bin 0 -> 4680 bytes .../__pycache__/_palettes.cpython-311.pyc | Bin 0 -> 5251 bytes .../rich/__pycache__/_pick.cpython-311.pyc | Bin 0 -> 796 bytes .../rich/__pycache__/_ratio.cpython-311.pyc | Bin 0 -> 7934 bytes .../__pycache__/_spinners.cpython-311.pyc | Bin 0 -> 13684 bytes .../rich/__pycache__/_stack.cpython-311.pyc | Bin 0 -> 1130 bytes .../rich/__pycache__/_timer.cpython-311.pyc | Bin 0 -> 983 bytes .../_win32_console.cpython-311.pyc | Bin 0 -> 30171 bytes .../rich/__pycache__/_windows.cpython-311.pyc | Bin 0 -> 2830 bytes .../_windows_renderer.cpython-311.pyc | Bin 0 -> 4021 bytes .../rich/__pycache__/_wrap.cpython-311.pyc | Bin 0 -> 2786 bytes .../rich/__pycache__/abc.cpython-311.pyc | Bin 0 -> 1927 bytes .../rich/__pycache__/align.cpython-311.pyc | Bin 0 -> 13476 bytes .../rich/__pycache__/ansi.cpython-311.pyc | Bin 0 -> 10452 bytes .../rich/__pycache__/bar.cpython-311.pyc | Bin 0 -> 4549 bytes .../rich/__pycache__/box.cpython-311.pyc | Bin 0 -> 12991 bytes .../rich/__pycache__/cells.cpython-311.pyc | Bin 0 -> 6441 bytes .../rich/__pycache__/color.cpython-311.pyc | Bin 0 -> 27572 bytes .../__pycache__/color_triplet.cpython-311.pyc | Bin 0 -> 1875 bytes .../rich/__pycache__/columns.cpython-311.pyc | Bin 0 -> 10646 bytes .../rich/__pycache__/console.cpython-311.pyc | Bin 0 -> 123162 bytes .../__pycache__/constrain.cpython-311.pyc | Bin 0 -> 2467 bytes .../__pycache__/containers.cpython-311.pyc | Bin 0 -> 10808 bytes .../rich/__pycache__/control.cpython-311.pyc | Bin 0 -> 11899 bytes .../default_styles.cpython-311.pyc | Bin 0 -> 12499 bytes .../rich/__pycache__/diagnose.cpython-311.pyc | Bin 0 -> 1822 bytes .../rich/__pycache__/emoji.cpython-311.pyc | Bin 0 -> 4800 bytes .../rich/__pycache__/errors.cpython-311.pyc | Bin 0 -> 2331 bytes .../__pycache__/file_proxy.cpython-311.pyc | Bin 0 -> 3779 bytes .../rich/__pycache__/filesize.cpython-311.pyc | Bin 0 -> 3303 bytes .../__pycache__/highlighter.cpython-311.pyc | Bin 0 -> 10990 bytes .../rich/__pycache__/json.cpython-311.pyc | Bin 0 -> 6683 bytes .../rich/__pycache__/jupyter.cpython-311.pyc | Bin 0 -> 6406 bytes .../rich/__pycache__/layout.cpython-311.pyc | Bin 0 -> 23313 bytes .../rich/__pycache__/live.cpython-311.pyc | Bin 0 -> 21134 bytes .../__pycache__/live_render.cpython-311.pyc | Bin 0 -> 5147 bytes .../rich/__pycache__/logging.cpython-311.pyc | Bin 0 -> 14518 bytes .../rich/__pycache__/markup.cpython-311.pyc | Bin 0 -> 10440 bytes .../rich/__pycache__/measure.cpython-311.pyc | Bin 0 -> 7273 bytes .../rich/__pycache__/padding.cpython-311.pyc | Bin 0 -> 7489 bytes .../rich/__pycache__/pager.cpython-311.pyc | Bin 0 -> 2247 bytes .../rich/__pycache__/palette.cpython-311.pyc | Bin 0 -> 5980 bytes .../rich/__pycache__/panel.cpython-311.pyc | Bin 0 -> 12736 bytes .../rich/__pycache__/pretty.cpython-311.pyc | Bin 0 -> 44829 bytes .../rich/__pycache__/progress.cpython-311.pyc | Bin 0 -> 82708 bytes .../__pycache__/progress_bar.cpython-311.pyc | Bin 0 -> 11014 bytes .../rich/__pycache__/prompt.cpython-311.pyc | Bin 0 -> 16380 bytes .../rich/__pycache__/protocol.cpython-311.pyc | Bin 0 -> 2098 bytes .../rich/__pycache__/region.cpython-311.pyc | Bin 0 -> 661 bytes .../rich/__pycache__/repr.cpython-311.pyc | Bin 0 -> 7660 bytes .../rich/__pycache__/rule.cpython-311.pyc | Bin 0 -> 7699 bytes .../rich/__pycache__/scope.cpython-311.pyc | Bin 0 -> 4353 bytes .../rich/__pycache__/screen.cpython-311.pyc | Bin 0 -> 2776 bytes .../rich/__pycache__/segment.cpython-311.pyc | Bin 0 -> 31543 bytes .../rich/__pycache__/spinner.cpython-311.pyc | Bin 0 -> 6892 bytes .../rich/__pycache__/status.cpython-311.pyc | Bin 0 -> 6760 bytes .../rich/__pycache__/style.cpython-311.pyc | Bin 0 -> 34333 bytes .../rich/__pycache__/styled.cpython-311.pyc | Bin 0 -> 2441 bytes .../rich/__pycache__/syntax.cpython-311.pyc | Bin 0 -> 42535 bytes .../rich/__pycache__/table.cpython-311.pyc | Bin 0 -> 48802 bytes .../terminal_theme.cpython-311.pyc | Bin 0 -> 3707 bytes .../rich/__pycache__/text.cpython-311.pyc | Bin 0 -> 65218 bytes .../rich/__pycache__/theme.cpython-311.pyc | Bin 0 -> 7145 bytes .../rich/__pycache__/themes.cpython-311.pyc | Bin 0 -> 357 bytes .../__pycache__/traceback.cpython-311.pyc | Bin 0 -> 31671 bytes .../rich/__pycache__/tree.cpython-311.pyc | Bin 0 -> 12528 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 | 78 + .../pip/_vendor/rich/_extension.py | 10 + .../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 | 83 + .../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 | 237 + .../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 | 618 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2612 +++++ .../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 | 188 + .../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 | 54 + .../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 | 373 + .../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 | 1029 ++ .../pip/_vendor/rich/progress.py | 1707 ++++ .../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 | 134 + .../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 | 136 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 773 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 945 ++ .../site-packages/pip/_vendor/rich/table.py | 1002 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1311 +++ .../site-packages/pip/_vendor/rich/theme.py | 112 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 677 ++ .../site-packages/pip/_vendor/rich/tree.py | 251 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 519 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 27795 bytes .../__pycache__/_asyncio.cpython-311.pyc | Bin 0 -> 4802 bytes .../__pycache__/_utils.cpython-311.pyc | Bin 0 -> 2067 bytes .../__pycache__/after.cpython-311.pyc | Bin 0 -> 1694 bytes .../__pycache__/before.cpython-311.pyc | Bin 0 -> 1528 bytes .../__pycache__/before_sleep.cpython-311.pyc | Bin 0 -> 2105 bytes .../tenacity/__pycache__/nap.cpython-311.pyc | Bin 0 -> 1567 bytes .../__pycache__/retry.cpython-311.pyc | Bin 0 -> 15041 bytes .../tenacity/__pycache__/stop.cpython-311.pyc | Bin 0 -> 5895 bytes .../__pycache__/tornadoweb.cpython-311.pyc | Bin 0 -> 2913 bytes .../tenacity/__pycache__/wait.cpython-311.pyc | Bin 0 -> 13367 bytes .../pip/_vendor/tenacity/_asyncio.py | 92 + .../pip/_vendor/tenacity/_utils.py | 68 + .../pip/_vendor/tenacity/after.py | 46 + .../pip/_vendor/tenacity/before.py | 41 + .../pip/_vendor/tenacity/before_sleep.py | 58 + .../site-packages/pip/_vendor/tenacity/nap.py | 43 + .../pip/_vendor/tenacity/retry.py | 240 + .../pip/_vendor/tenacity/stop.py | 96 + .../pip/_vendor/tenacity/tornadoweb.py | 59 + .../pip/_vendor/tenacity/wait.py | 232 + .../pip/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 412 bytes .../tomli/__pycache__/_parser.cpython-311.pyc | Bin 0 -> 30851 bytes .../tomli/__pycache__/_re.cpython-311.pyc | Bin 0 -> 4491 bytes .../tomli/__pycache__/_types.cpython-311.pyc | Bin 0 -> 404 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/typing_extensions.py | 2209 +++++ .../pip/_vendor/urllib3/__init__.py | 102 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3710 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 18298 bytes .../__pycache__/_version.cpython-311.pyc | Bin 0 -> 220 bytes .../__pycache__/connection.cpython-311.pyc | Bin 0 -> 21894 bytes .../connectionpool.cpython-311.pyc | Bin 0 -> 37637 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 16124 bytes .../__pycache__/fields.cpython-311.pyc | Bin 0 -> 11417 bytes .../__pycache__/filepost.cpython-311.pyc | Bin 0 -> 4498 bytes .../__pycache__/poolmanager.cpython-311.pyc | Bin 0 -> 21821 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 6661 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 36544 bytes .../pip/_vendor/urllib3/_collections.py | 337 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 567 ++ .../pip/_vendor/urllib3/connectionpool.py | 1110 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 206 bytes .../_appengine_environ.cpython-311.pyc | Bin 0 -> 1945 bytes .../__pycache__/appengine.cpython-311.pyc | Bin 0 -> 12152 bytes .../__pycache__/ntlmpool.cpython-311.pyc | Bin 0 -> 6229 bytes .../__pycache__/pyopenssl.cpython-311.pyc | Bin 0 -> 25738 bytes .../securetransport.cpython-311.pyc | Bin 0 -> 36845 bytes .../contrib/__pycache__/socks.cpython-311.pyc | Bin 0 -> 8090 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 223 bytes .../__pycache__/bindings.cpython-311.pyc | Bin 0 -> 16970 bytes .../__pycache__/low_level.cpython-311.pyc | Bin 0 -> 15607 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-311.pyc | Bin 0 -> 207 bytes .../packages/__pycache__/six.cpython-311.pyc | Bin 0 -> 46449 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 217 bytes .../__pycache__/makefile.cpython-311.pyc | Bin 0 -> 1964 bytes .../urllib3/packages/backports/makefile.py | 51 + .../pip/_vendor/urllib3/packages/six.py | 1076 ++ .../pip/_vendor/urllib3/poolmanager.py | 537 + .../pip/_vendor/urllib3/request.py | 170 + .../pip/_vendor/urllib3/response.py | 879 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1409 bytes .../__pycache__/connection.cpython-311.pyc | Bin 0 -> 5136 bytes .../util/__pycache__/proxy.cpython-311.pyc | Bin 0 -> 1718 bytes .../util/__pycache__/queue.cpython-311.pyc | Bin 0 -> 1501 bytes .../util/__pycache__/request.cpython-311.pyc | Bin 0 -> 4621 bytes .../util/__pycache__/response.cpython-311.pyc | Bin 0 -> 3490 bytes .../util/__pycache__/retry.cpython-311.pyc | Bin 0 -> 22758 bytes .../util/__pycache__/ssl_.cpython-311.pyc | Bin 0 -> 16821 bytes .../ssl_match_hostname.cpython-311.pyc | Bin 0 -> 5800 bytes .../__pycache__/ssltransport.cpython-311.pyc | Bin 0 -> 11629 bytes .../util/__pycache__/timeout.cpython-311.pyc | Bin 0 -> 11037 bytes .../util/__pycache__/url.cpython-311.pyc | Bin 0 -> 17561 bytes .../util/__pycache__/wait.cpython-311.pyc | Bin 0 -> 5003 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 | 620 ++ .../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 | 268 + .../pip/_vendor/urllib3/util/url.py | 435 + .../pip/_vendor/urllib3/util/wait.py | 152 + .../site-packages/pip/_vendor/vendor.txt | 23 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 12883 bytes .../__pycache__/labels.cpython-311.pyc | Bin 0 -> 7283 bytes .../__pycache__/mklabels.cpython-311.pyc | Bin 0 -> 3211 bytes .../__pycache__/tests.cpython-311.pyc | Bin 0 -> 11189 bytes .../x_user_defined.cpython-311.pyc | Bin 0 -> 3563 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.11/site-packages/pip/py.typed | 4 + .../site-packages/pkg_resources/__init__.py | 3282 +++++++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 156114 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 200 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 97417 bytes .../_vendor/__pycache__/zipp.cpython-311.pyc | Bin 0 -> 15993 bytes .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 834 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 10751 bytes .../__pycache__/_common.cpython-311.pyc | Bin 0 -> 4278 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 5563 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1396 bytes .../__pycache__/_legacy.cpython-311.pyc | Bin 0 -> 6494 bytes .../__pycache__/abc.cpython-311.pyc | Bin 0 -> 7495 bytes .../__pycache__/readers.cpython-311.pyc | Bin 0 -> 8369 bytes .../__pycache__/simple.cpython-311.pyc | Bin 0 -> 6391 bytes .../_vendor/importlib_resources/_adapters.py | 170 + .../_vendor/importlib_resources/_common.py | 104 + .../_vendor/importlib_resources/_compat.py | 98 + .../_vendor/importlib_resources/_itertools.py | 35 + .../_vendor/importlib_resources/_legacy.py | 121 + .../_vendor/importlib_resources/abc.py | 137 + .../_vendor/importlib_resources/readers.py | 122 + .../_vendor/importlib_resources/simple.py | 116 + .../pkg_resources/_vendor/jaraco/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 207 bytes .../__pycache__/context.cpython-311.pyc | Bin 0 -> 10982 bytes .../__pycache__/functools.cpython-311.pyc | Bin 0 -> 20293 bytes .../pkg_resources/_vendor/jaraco/context.py | 253 + .../pkg_resources/_vendor/jaraco/functools.py | 525 + .../_vendor/jaraco/text/__init__.py | 599 ++ .../text/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 26610 bytes .../_vendor/more_itertools/__init__.py | 6 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 379 bytes .../__pycache__/more.cpython-311.pyc | Bin 0 -> 169501 bytes .../__pycache__/recipes.cpython-311.pyc | Bin 0 -> 33521 bytes .../_vendor/more_itertools/more.py | 4346 +++++++++ .../_vendor/more_itertools/recipes.py | 841 ++ .../_vendor/packaging/__about__.py | 26 + .../_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-311.pyc | Bin 0 -> 651 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 572 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13238 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 8006 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3694 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16543 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7658 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34372 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21357 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6692 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21884 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 61 + .../_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 802 ++ .../pkg_resources/_vendor/packaging/tags.py | 487 + .../pkg_resources/_vendor/packaging/utils.py | 136 + .../_vendor/packaging/version.py | 504 + .../_vendor/platformdirs/__init__.py | 342 + .../_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 12832 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 2124 bytes .../__pycache__/android.cpython-311.pyc | Bin 0 -> 6366 bytes .../__pycache__/api.cpython-311.pyc | Bin 0 -> 7193 bytes .../__pycache__/macos.cpython-311.pyc | Bin 0 -> 4603 bytes .../__pycache__/unix.cpython-311.pyc | Bin 0 -> 11035 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 322 bytes .../__pycache__/windows.cpython-311.pyc | Bin 0 -> 9971 bytes .../_vendor/platformdirs/android.py | 120 + .../pkg_resources/_vendor/platformdirs/api.py | 156 + .../_vendor/platformdirs/macos.py | 64 + .../_vendor/platformdirs/unix.py | 181 + .../_vendor/platformdirs/version.py | 4 + .../_vendor/platformdirs/windows.py | 184 + .../_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 8345 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8471 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14793 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277645 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12935 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53636 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36319 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19515 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15373 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14272 bytes .../_vendor/pyparsing/actions.py | 207 + .../pkg_resources/_vendor/pyparsing/common.py | 424 + .../pkg_resources/_vendor/pyparsing/core.py | 5814 +++++++++++ .../_vendor/pyparsing/diagram/__init__.py | 642 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 28008 bytes .../_vendor/pyparsing/exceptions.py | 267 + .../_vendor/pyparsing/helpers.py | 1088 +++ .../_vendor/pyparsing/results.py | 760 ++ .../_vendor/pyparsing/testing.py | 331 + .../_vendor/pyparsing/unicode.py | 352 + .../pkg_resources/_vendor/pyparsing/util.py | 235 + .../_vendor/typing_extensions.py | 2209 +++++ .../pkg_resources/_vendor/zipp.py | 329 + .../pkg_resources/extern/__init__.py | 81 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 4323 bytes .../pydantic-2.11.1.dist-info/INSTALLER | 1 + .../pydantic-2.11.1.dist-info/METADATA | 679 ++ .../pydantic-2.11.1.dist-info/RECORD | 215 + .../pydantic-2.11.1.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../site-packages/pydantic/__init__.py | 445 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 13393 bytes .../__pycache__/_migration.cpython-311.pyc | Bin 0 -> 11366 bytes .../alias_generators.cpython-311.pyc | Bin 0 -> 3523 bytes .../__pycache__/aliases.cpython-311.pyc | Bin 0 -> 7211 bytes .../annotated_handlers.cpython-311.pyc | Bin 0 -> 5847 bytes .../class_validators.cpython-311.pyc | Bin 0 -> 396 bytes .../__pycache__/color.cpython-311.pyc | Bin 0 -> 32484 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 8002 bytes .../__pycache__/dataclasses.cpython-311.pyc | Bin 0 -> 15002 bytes .../datetime_parse.cpython-311.pyc | Bin 0 -> 396 bytes .../__pycache__/decorator.cpython-311.pyc | Bin 0 -> 386 bytes .../__pycache__/env_settings.cpython-311.pyc | Bin 0 -> 392 bytes .../error_wrappers.cpython-311.pyc | Bin 0 -> 396 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 8861 bytes .../__pycache__/fields.cpython-311.pyc | Bin 0 -> 64422 bytes .../functional_serializers.cpython-311.pyc | Bin 0 -> 18727 bytes .../functional_validators.cpython-311.pyc | Bin 0 -> 34323 bytes .../__pycache__/generics.cpython-311.pyc | Bin 0 -> 384 bytes .../pydantic/__pycache__/json.cpython-311.pyc | Bin 0 -> 376 bytes .../__pycache__/json_schema.cpython-311.pyc | Bin 0 -> 127691 bytes .../pydantic/__pycache__/main.cpython-311.pyc | Bin 0 -> 79125 bytes .../pydantic/__pycache__/mypy.cpython-311.pyc | Bin 0 -> 65911 bytes .../__pycache__/networks.cpython-311.pyc | Bin 0 -> 53630 bytes .../__pycache__/parse.cpython-311.pyc | Bin 0 -> 378 bytes .../__pycache__/root_model.cpython-311.pyc | Bin 0 -> 8594 bytes .../__pycache__/schema.cpython-311.pyc | Bin 0 -> 380 bytes .../__pycache__/tools.cpython-311.pyc | Bin 0 -> 378 bytes .../__pycache__/type_adapter.cpython-311.pyc | Bin 0 -> 32301 bytes .../__pycache__/types.cpython-311.pyc | Bin 0 -> 103765 bytes .../__pycache__/typing.cpython-311.pyc | Bin 0 -> 376 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 378 bytes .../validate_call_decorator.cpython-311.pyc | Bin 0 -> 6042 bytes .../__pycache__/validators.cpython-311.pyc | Bin 0 -> 388 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 4591 bytes .../__pycache__/warnings.cpython-311.pyc | Bin 0 -> 6671 bytes .../pydantic/_internal/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 197 bytes .../__pycache__/_config.cpython-311.pyc | Bin 0 -> 17833 bytes .../_core_metadata.cpython-311.pyc | Bin 0 -> 5064 bytes .../__pycache__/_core_utils.cpython-311.pyc | Bin 0 -> 8972 bytes .../__pycache__/_dataclasses.cpython-311.pyc | Bin 0 -> 10382 bytes .../__pycache__/_decorators.cpython-311.pyc | Bin 0 -> 40339 bytes .../_decorators_v1.cpython-311.pyc | Bin 0 -> 9919 bytes .../_discriminated_union.cpython-311.pyc | Bin 0 -> 23296 bytes .../_docs_extraction.cpython-311.pyc | Bin 0 -> 5676 bytes .../__pycache__/_fields.cpython-311.pyc | Bin 0 -> 19827 bytes .../__pycache__/_forward_ref.cpython-311.pyc | Bin 0 -> 1471 bytes .../_generate_schema.cpython-311.pyc | Bin 0 -> 146128 bytes .../__pycache__/_generics.cpython-311.pyc | Bin 0 -> 27031 bytes .../__pycache__/_git.cpython-311.pyc | Bin 0 -> 1731 bytes .../__pycache__/_import_utils.cpython-311.pyc | Bin 0 -> 968 bytes .../_internal_dataclass.cpython-311.pyc | Bin 0 -> 344 bytes .../_known_annotated_metadata.cpython-311.pyc | Bin 0 -> 15788 bytes .../__pycache__/_mock_val_ser.cpython-311.pyc | Bin 0 -> 12344 bytes .../_model_construction.cpython-311.pyc | Bin 0 -> 38248 bytes .../_namespace_utils.cpython-311.pyc | Bin 0 -> 13474 bytes .../__pycache__/_repr.cpython-311.pyc | Bin 0 -> 8766 bytes .../_schema_gather.cpython-311.pyc | Bin 0 -> 9049 bytes .../_schema_generation_shared.cpython-311.pyc | Bin 0 -> 6772 bytes .../__pycache__/_serializers.cpython-311.pyc | Bin 0 -> 2108 bytes .../__pycache__/_signature.cpython-311.pyc | Bin 0 -> 7394 bytes .../__pycache__/_typing_extra.cpython-311.pyc | Bin 0 -> 28825 bytes .../__pycache__/_utils.cpython-311.pyc | Bin 0 -> 22002 bytes .../_validate_call.cpython-311.pyc | Bin 0 -> 7206 bytes .../__pycache__/_validators.cpython-311.pyc | Bin 0 -> 25753 bytes .../pydantic/_internal/_config.py | 373 + .../pydantic/_internal/_core_metadata.py | 97 + .../pydantic/_internal/_core_utils.py | 182 + .../pydantic/_internal/_dataclasses.py | 235 + .../pydantic/_internal/_decorators.py | 838 ++ .../pydantic/_internal/_decorators_v1.py | 174 + .../_internal/_discriminated_union.py | 479 + .../pydantic/_internal/_docs_extraction.py | 108 + .../pydantic/_internal/_fields.py | 459 + .../pydantic/_internal/_forward_ref.py | 23 + .../pydantic/_internal/_generate_schema.py | 2862 ++++++ .../pydantic/_internal/_generics.py | 547 ++ .../site-packages/pydantic/_internal/_git.py | 27 + .../pydantic/_internal/_import_utils.py | 20 + .../pydantic/_internal/_internal_dataclass.py | 7 + .../_internal/_known_annotated_metadata.py | 397 + .../pydantic/_internal/_mock_val_ser.py | 228 + .../pydantic/_internal/_model_construction.py | 792 ++ .../pydantic/_internal/_namespace_utils.py | 293 + .../site-packages/pydantic/_internal/_repr.py | 125 + .../pydantic/_internal/_schema_gather.py | 204 + .../_internal/_schema_generation_shared.py | 125 + .../pydantic/_internal/_serializers.py | 53 + .../pydantic/_internal/_signature.py | 188 + .../pydantic/_internal/_typing_extra.py | 714 ++ .../pydantic/_internal/_utils.py | 429 + .../pydantic/_internal/_validate_call.py | 140 + .../pydantic/_internal/_validators.py | 532 + .../site-packages/pydantic/_migration.py | 308 + .../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 | 1213 +++ .../site-packages/pydantic/dataclasses.py | 374 + .../site-packages/pydantic/datetime_parse.py | 5 + .../site-packages/pydantic/decorator.py | 5 + .../pydantic/deprecated/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 198 bytes .../class_validators.cpython-311.pyc | Bin 0 -> 12850 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 4864 bytes .../copy_internals.cpython-311.pyc | Bin 0 -> 9614 bytes .../__pycache__/decorator.cpython-311.pyc | Bin 0 -> 15632 bytes .../__pycache__/json.cpython-311.pyc | Bin 0 -> 6822 bytes .../__pycache__/parse.cpython-311.pyc | Bin 0 -> 3666 bytes .../__pycache__/tools.cpython-311.pyc | Bin 0 -> 3895 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 | 190 + .../pydantic/experimental/__init__.py | 10 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 601 bytes .../arguments_schema.cpython-311.pyc | Bin 0 -> 2564 bytes .../__pycache__/pipeline.cpython-311.pyc | Bin 0 -> 38879 bytes .../pydantic/experimental/arguments_schema.py | 44 + .../pydantic/experimental/pipeline.py | 667 ++ .../site-packages/pydantic/fields.py | 1542 +++ .../pydantic/functional_serializers.py | 450 + .../pydantic/functional_validators.py | 828 ++ .../site-packages/pydantic/generics.py | 5 + .../python3.11/site-packages/pydantic/json.py | 5 + .../site-packages/pydantic/json_schema.py | 2695 +++++ .../python3.11/site-packages/pydantic/main.py | 1772 ++++ .../python3.11/site-packages/pydantic/mypy.py | 1373 +++ .../site-packages/pydantic/networks.py | 1312 +++ .../site-packages/pydantic/parse.py | 5 + .../site-packages/pydantic/plugin/__init__.py | 188 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 9096 bytes .../__pycache__/_loader.cpython-311.pyc | Bin 0 -> 2548 bytes .../_schema_validator.cpython-311.pyc | Bin 0 -> 7653 bytes .../site-packages/pydantic/plugin/_loader.py | 57 + .../pydantic/plugin/_schema_validator.py | 140 + .../site-packages/pydantic/py.typed | 0 .../site-packages/pydantic/root_model.py | 157 + .../site-packages/pydantic/schema.py | 5 + .../site-packages/pydantic/tools.py | 5 + .../site-packages/pydantic/type_adapter.py | 727 ++ .../site-packages/pydantic/types.py | 3285 +++++++ .../site-packages/pydantic/typing.py | 5 + .../site-packages/pydantic/utils.py | 5 + .../site-packages/pydantic/v1/__init__.py | 131 + .../v1/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2448 bytes .../_hypothesis_plugin.cpython-311.pyc | Bin 0 -> 20249 bytes .../annotated_types.cpython-311.pyc | Bin 0 -> 4695 bytes .../class_validators.cpython-311.pyc | Bin 0 -> 22808 bytes .../v1/__pycache__/color.cpython-311.pyc | Bin 0 -> 28227 bytes .../v1/__pycache__/config.cpython-311.pyc | Bin 0 -> 10055 bytes .../__pycache__/dataclasses.cpython-311.pyc | Bin 0 -> 25826 bytes .../datetime_parse.cpython-311.pyc | Bin 0 -> 11986 bytes .../v1/__pycache__/decorator.cpython-311.pyc | Bin 0 -> 15689 bytes .../__pycache__/env_settings.cpython-311.pyc | Bin 0 -> 20040 bytes .../error_wrappers.cpython-311.pyc | Bin 0 -> 10057 bytes .../v1/__pycache__/errors.cpython-311.pyc | Bin 0 -> 36549 bytes .../v1/__pycache__/fields.cpython-311.pyc | Bin 0 -> 62990 bytes .../v1/__pycache__/generics.cpython-311.pyc | Bin 0 -> 19728 bytes .../v1/__pycache__/json.cpython-311.pyc | Bin 0 -> 5697 bytes .../v1/__pycache__/main.cpython-311.pyc | Bin 0 -> 54959 bytes .../v1/__pycache__/mypy.cpython-311.pyc | Bin 0 -> 50505 bytes .../v1/__pycache__/networks.cpython-311.pyc | Bin 0 -> 34188 bytes .../v1/__pycache__/parse.cpython-311.pyc | Bin 0 -> 3045 bytes .../v1/__pycache__/schema.cpython-311.pyc | Bin 0 -> 54644 bytes .../v1/__pycache__/tools.cpython-311.pyc | Bin 0 -> 4472 bytes .../v1/__pycache__/types.cpython-311.pyc | Bin 0 -> 55104 bytes .../v1/__pycache__/typing.cpython-311.pyc | Bin 0 -> 25282 bytes .../v1/__pycache__/utils.cpython-311.pyc | Bin 0 -> 40741 bytes .../v1/__pycache__/validators.cpython-311.pyc | Bin 0 -> 34983 bytes .../v1/__pycache__/version.cpython-311.pyc | Bin 0 -> 2207 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 | 1107 +++ .../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 | 608 ++ .../site-packages/pydantic/v1/utils.py | 804 ++ .../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 | 86 + .../site-packages/pydantic/warnings.py | 96 + .../pydantic_core-2.33.0.dist-info/INSTALLER | 1 + .../pydantic_core-2.33.0.dist-info/METADATA | 160 + .../pydantic_core-2.33.0.dist-info/RECORD | 12 + .../pydantic_core-2.33.0.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../site-packages/pydantic_core/__init__.py | 144 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3770 bytes .../__pycache__/core_schema.cpython-311.pyc | Bin 0 -> 156555 bytes ...antic_core.cpython-311-x86_64-linux-gnu.so | Bin 0 -> 4765960 bytes .../pydantic_core/_pydantic_core.pyi | 1039 ++ .../pydantic_core/core_schema.py | 4325 ++++++++ .../site-packages/pydantic_core/py.typed | 0 .../setuptools-66.1.1.dist-info/INSTALLER | 1 + .../setuptools-66.1.1.dist-info/LICENSE | 19 + .../setuptools-66.1.1.dist-info/METADATA | 137 + .../setuptools-66.1.1.dist-info/RECORD | 484 + .../setuptools-66.1.1.dist-info/REQUESTED | 0 .../setuptools-66.1.1.dist-info/WHEEL | 5 + .../entry_points.txt | 57 + .../setuptools-66.1.1.dist-info/top_level.txt | 4 + .../site-packages/setuptools/__init__.py | 268 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 13928 bytes .../_deprecation_warning.cpython-311.pyc | Bin 0 -> 644 bytes .../__pycache__/_entry_points.cpython-311.pyc | Bin 0 -> 5201 bytes .../__pycache__/_imp.cpython-311.pyc | Bin 0 -> 3657 bytes .../__pycache__/_importlib.cpython-311.pyc | Bin 0 -> 1957 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1156 bytes .../__pycache__/_path.cpython-311.pyc | Bin 0 -> 1477 bytes .../__pycache__/_reqs.cpython-311.pyc | Bin 0 -> 1138 bytes .../__pycache__/archive_util.cpython-311.pyc | Bin 0 -> 10166 bytes .../__pycache__/build_meta.cpython-311.pyc | Bin 0 -> 28149 bytes .../__pycache__/dep_util.cpython-311.pyc | Bin 0 -> 1292 bytes .../__pycache__/depends.cpython-311.pyc | Bin 0 -> 7977 bytes .../__pycache__/discovery.cpython-311.pyc | Bin 0 -> 31130 bytes .../__pycache__/dist.cpython-311.pyc | Bin 0 -> 63797 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 2953 bytes .../__pycache__/extension.cpython-311.pyc | Bin 0 -> 6809 bytes .../__pycache__/glob.cpython-311.pyc | Bin 0 -> 6566 bytes .../__pycache__/installer.cpython-311.pyc | Bin 0 -> 5616 bytes .../__pycache__/launch.cpython-311.pyc | Bin 0 -> 1532 bytes .../__pycache__/logging.cpython-311.pyc | Bin 0 -> 2099 bytes .../__pycache__/monkey.cpython-311.pyc | Bin 0 -> 7009 bytes .../__pycache__/msvc.cpython-311.pyc | Bin 0 -> 64182 bytes .../__pycache__/namespaces.cpython-311.pyc | Bin 0 -> 5664 bytes .../__pycache__/package_index.cpython-311.pyc | Bin 0 -> 61937 bytes .../__pycache__/py34compat.cpython-311.pyc | Bin 0 -> 719 bytes .../__pycache__/sandbox.cpython-311.pyc | Bin 0 -> 27335 bytes .../__pycache__/unicode_utils.cpython-311.pyc | Bin 0 -> 1821 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 439 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 15495 bytes .../windows_support.cpython-311.pyc | Bin 0 -> 1436 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 14 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 563 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 8533 bytes .../__pycache__/_functools.cpython-311.pyc | Bin 0 -> 865 bytes .../__pycache__/_log.cpython-311.pyc | Bin 0 -> 282 bytes .../__pycache__/_macos_compat.cpython-311.pyc | Bin 0 -> 574 bytes .../__pycache__/_msvccompiler.cpython-311.pyc | Bin 0 -> 25076 bytes .../__pycache__/archive_util.cpython-311.pyc | Bin 0 -> 10624 bytes .../__pycache__/bcppcompiler.cpython-311.pyc | Bin 0 -> 13450 bytes .../__pycache__/ccompiler.cpython-311.pyc | Bin 0 -> 46319 bytes .../__pycache__/cmd.cpython-311.pyc | Bin 0 -> 18843 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 6044 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 9934 bytes .../cygwinccompiler.cpython-311.pyc | Bin 0 -> 13628 bytes .../__pycache__/debug.cpython-311.pyc | Bin 0 -> 326 bytes .../__pycache__/dep_util.cpython-311.pyc | Bin 0 -> 3988 bytes .../__pycache__/dir_util.cpython-311.pyc | Bin 0 -> 10369 bytes .../__pycache__/dist.cpython-311.pyc | Bin 0 -> 55492 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 6799 bytes .../__pycache__/extension.cpython-311.pyc | Bin 0 -> 10180 bytes .../__pycache__/fancy_getopt.cpython-311.pyc | Bin 0 -> 17239 bytes .../__pycache__/file_util.cpython-311.pyc | Bin 0 -> 10673 bytes .../__pycache__/filelist.cpython-311.pyc | Bin 0 -> 17613 bytes .../__pycache__/log.cpython-311.pyc | Bin 0 -> 2697 bytes .../__pycache__/msvc9compiler.cpython-311.pyc | Bin 0 -> 33562 bytes .../__pycache__/msvccompiler.cpython-311.pyc | Bin 0 -> 26974 bytes .../__pycache__/py38compat.cpython-311.pyc | Bin 0 -> 626 bytes .../__pycache__/py39compat.cpython-311.pyc | Bin 0 -> 994 bytes .../__pycache__/spawn.cpython-311.pyc | Bin 0 -> 4438 bytes .../__pycache__/sysconfig.cpython-311.pyc | Bin 0 -> 22075 bytes .../__pycache__/text_file.cpython-311.pyc | Bin 0 -> 11275 bytes .../__pycache__/unixccompiler.cpython-311.pyc | Bin 0 -> 16498 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 20849 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 11351 bytes .../versionpredicate.cpython-311.pyc | Bin 0 -> 7628 bytes .../setuptools/_distutils/_collections.py | 194 + .../setuptools/_distutils/_functools.py | 20 + .../setuptools/_distutils/_log.py | 4 + .../setuptools/_distutils/_macos_compat.py | 12 + .../setuptools/_distutils/_msvccompiler.py | 572 ++ .../setuptools/_distutils/archive_util.py | 280 + .../setuptools/_distutils/bcppcompiler.py | 408 + .../setuptools/_distutils/ccompiler.py | 1220 +++ .../setuptools/_distutils/cmd.py | 435 + .../setuptools/_distutils/command/__init__.py | 25 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 546 bytes .../_framework_compat.cpython-311.pyc | Bin 0 -> 2787 bytes .../command/__pycache__/bdist.cpython-311.pyc | Bin 0 -> 6005 bytes .../__pycache__/bdist_dumb.cpython-311.pyc | Bin 0 -> 5725 bytes .../__pycache__/bdist_rpm.cpython-311.pyc | Bin 0 -> 23259 bytes .../command/__pycache__/build.cpython-311.pyc | Bin 0 -> 6060 bytes .../__pycache__/build_clib.cpython-311.pyc | Bin 0 -> 7768 bytes .../__pycache__/build_ext.cpython-311.pyc | Bin 0 -> 30278 bytes .../__pycache__/build_py.cpython-311.pyc | Bin 0 -> 17604 bytes .../__pycache__/build_scripts.cpython-311.pyc | Bin 0 -> 7858 bytes .../command/__pycache__/check.cpython-311.pyc | Bin 0 -> 7514 bytes .../command/__pycache__/clean.cpython-311.pyc | Bin 0 -> 3190 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 16227 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 29379 bytes .../__pycache__/install_data.cpython-311.pyc | Bin 0 -> 3767 bytes .../install_egg_info.cpython-311.pyc | Bin 0 -> 5222 bytes .../install_headers.cpython-311.pyc | Bin 0 -> 2355 bytes .../__pycache__/install_lib.cpython-311.pyc | Bin 0 -> 8676 bytes .../install_scripts.cpython-311.pyc | Bin 0 -> 3162 bytes .../__pycache__/py37compat.cpython-311.pyc | Bin 0 -> 1543 bytes .../__pycache__/register.cpython-311.pyc | Bin 0 -> 15561 bytes .../command/__pycache__/sdist.cpython-311.pyc | Bin 0 -> 23773 bytes .../__pycache__/upload.cpython-311.pyc | Bin 0 -> 10427 bytes .../_distutils/command/_framework_compat.py | 55 + .../setuptools/_distutils/command/bdist.py | 157 + .../_distutils/command/bdist_dumb.py | 144 + .../_distutils/command/bdist_rpm.py | 615 ++ .../setuptools/_distutils/command/build.py | 153 + .../_distutils/command/build_clib.py | 208 + .../_distutils/command/build_ext.py | 789 ++ .../setuptools/_distutils/command/build_py.py | 407 + .../_distutils/command/build_scripts.py | 173 + .../setuptools/_distutils/command/check.py | 151 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 377 + .../setuptools/_distutils/command/install.py | 814 ++ .../_distutils/command/install_data.py | 84 + .../_distutils/command/install_egg_info.py | 92 + .../_distutils/command/install_headers.py | 45 + .../_distutils/command/install_lib.py | 238 + .../_distutils/command/install_scripts.py | 61 + .../_distutils/command/py37compat.py | 31 + .../setuptools/_distutils/command/register.py | 321 + .../setuptools/_distutils/command/sdist.py | 531 + .../setuptools/_distutils/command/upload.py | 207 + .../setuptools/_distutils/config.py | 139 + .../setuptools/_distutils/core.py | 291 + .../setuptools/_distutils/cygwinccompiler.py | 358 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 96 + .../setuptools/_distutils/dir_util.py | 243 + .../setuptools/_distutils/dist.py | 1287 +++ .../setuptools/_distutils/errors.py | 127 + .../setuptools/_distutils/extension.py | 248 + .../setuptools/_distutils/fancy_getopt.py | 470 + .../setuptools/_distutils/file_util.py | 249 + .../setuptools/_distutils/filelist.py | 371 + .../setuptools/_distutils/log.py | 57 + .../setuptools/_distutils/msvc9compiler.py | 832 ++ .../setuptools/_distutils/msvccompiler.py | 695 ++ .../setuptools/_distutils/py38compat.py | 8 + .../setuptools/_distutils/py39compat.py | 22 + .../setuptools/_distutils/spawn.py | 109 + .../setuptools/_distutils/sysconfig.py | 552 ++ .../setuptools/_distutils/text_file.py | 287 + .../setuptools/_distutils/unixccompiler.py | 401 + .../setuptools/_distutils/util.py | 513 + .../setuptools/_distutils/version.py | 358 + .../setuptools/_distutils/versionpredicate.py | 175 + .../site-packages/setuptools/_entry_points.py | 94 + .../site-packages/setuptools/_imp.py | 82 + .../site-packages/setuptools/_importlib.py | 47 + .../site-packages/setuptools/_itertools.py | 23 + .../site-packages/setuptools/_path.py | 29 + .../site-packages/setuptools/_reqs.py | 19 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 197 bytes .../__pycache__/ordered_set.cpython-311.pyc | Bin 0 -> 21783 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 107614 bytes .../_vendor/__pycache__/zipp.cpython-311.pyc | Bin 0 -> 15990 bytes .../_vendor/importlib_metadata/__init__.py | 1047 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 58236 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 3849 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 2196 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 2718 bytes .../__pycache__/_functools.cpython-311.pyc | Bin 0 -> 3636 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 2599 bytes .../__pycache__/_meta.cpython-311.pyc | Bin 0 -> 3003 bytes .../__pycache__/_text.cpython-311.pyc | Bin 0 -> 4394 bytes .../_vendor/importlib_metadata/_adapters.py | 68 + .../importlib_metadata/_collections.py | 30 + .../_vendor/importlib_metadata/_compat.py | 71 + .../_vendor/importlib_metadata/_functools.py | 104 + .../_vendor/importlib_metadata/_itertools.py | 73 + .../_vendor/importlib_metadata/_meta.py | 48 + .../_vendor/importlib_metadata/_text.py | 99 + .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 831 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 10748 bytes .../__pycache__/_common.cpython-311.pyc | Bin 0 -> 4275 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 5560 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1393 bytes .../__pycache__/_legacy.cpython-311.pyc | Bin 0 -> 6491 bytes .../__pycache__/abc.cpython-311.pyc | Bin 0 -> 7492 bytes .../__pycache__/readers.cpython-311.pyc | Bin 0 -> 8366 bytes .../__pycache__/simple.cpython-311.pyc | Bin 0 -> 6388 bytes .../_vendor/importlib_resources/_adapters.py | 170 + .../_vendor/importlib_resources/_common.py | 104 + .../_vendor/importlib_resources/_compat.py | 98 + .../_vendor/importlib_resources/_itertools.py | 35 + .../_vendor/importlib_resources/_legacy.py | 121 + .../_vendor/importlib_resources/abc.py | 137 + .../_vendor/importlib_resources/readers.py | 122 + .../_vendor/importlib_resources/simple.py | 116 + .../setuptools/_vendor/jaraco/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 204 bytes .../__pycache__/context.cpython-311.pyc | Bin 0 -> 10979 bytes .../__pycache__/functools.cpython-311.pyc | Bin 0 -> 20284 bytes .../setuptools/_vendor/jaraco/context.py | 253 + .../setuptools/_vendor/jaraco/functools.py | 525 + .../_vendor/jaraco/text/__init__.py | 599 ++ .../text/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 26598 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 297 bytes .../__pycache__/more.cpython-311.pyc | Bin 0 -> 149184 bytes .../__pycache__/recipes.cpython-311.pyc | Bin 0 -> 23766 bytes .../setuptools/_vendor/more_itertools/more.py | 3824 ++++++++ .../_vendor/more_itertools/recipes.py | 620 ++ .../setuptools/_vendor/ordered_set.py | 488 + .../setuptools/_vendor/packaging/__about__.py | 26 + .../setuptools/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-311.pyc | Bin 0 -> 648 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 569 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13235 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 8003 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3691 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16537 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7652 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34369 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21354 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6689 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21881 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 61 + .../setuptools/_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 802 ++ .../setuptools/_vendor/packaging/tags.py | 487 + .../setuptools/_vendor/packaging/utils.py | 136 + .../setuptools/_vendor/packaging/version.py | 504 + .../setuptools/_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 8342 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8468 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14790 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277642 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12932 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53633 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36316 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19512 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15370 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14269 bytes .../setuptools/_vendor/pyparsing/actions.py | 207 + .../setuptools/_vendor/pyparsing/common.py | 424 + .../setuptools/_vendor/pyparsing/core.py | 5814 +++++++++++ .../_vendor/pyparsing/diagram/__init__.py | 642 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 28005 bytes .../_vendor/pyparsing/exceptions.py | 267 + .../setuptools/_vendor/pyparsing/helpers.py | 1088 +++ .../setuptools/_vendor/pyparsing/results.py | 760 ++ .../setuptools/_vendor/pyparsing/testing.py | 331 + .../setuptools/_vendor/pyparsing/unicode.py | 352 + .../setuptools/_vendor/pyparsing/util.py | 235 + .../setuptools/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 419 bytes .../tomli/__pycache__/_parser.cpython-311.pyc | Bin 0 -> 30858 bytes .../tomli/__pycache__/_re.cpython-311.pyc | Bin 0 -> 4498 bytes .../tomli/__pycache__/_types.cpython-311.pyc | Bin 0 -> 411 bytes .../setuptools/_vendor/tomli/_parser.py | 691 ++ .../setuptools/_vendor/tomli/_re.py | 107 + .../setuptools/_vendor/tomli/_types.py | 10 + .../setuptools/_vendor/typing_extensions.py | 2296 +++++ .../site-packages/setuptools/_vendor/zipp.py | 329 + .../site-packages/setuptools/archive_util.py | 213 + .../site-packages/setuptools/build_meta.py | 512 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli-arm64.exe | Bin 0 -> 137216 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 12 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 638 bytes .../command/__pycache__/alias.cpython-311.pyc | Bin 0 -> 3905 bytes .../__pycache__/bdist_egg.cpython-311.pyc | Bin 0 -> 25587 bytes .../__pycache__/bdist_rpm.cpython-311.pyc | Bin 0 -> 2193 bytes .../command/__pycache__/build.cpython-311.pyc | Bin 0 -> 6993 bytes .../__pycache__/build_clib.cpython-311.pyc | Bin 0 -> 4168 bytes .../__pycache__/build_ext.cpython-311.pyc | Bin 0 -> 22013 bytes .../__pycache__/build_py.cpython-311.pyc | Bin 0 -> 23179 bytes .../__pycache__/develop.cpython-311.pyc | Bin 0 -> 10921 bytes .../__pycache__/dist_info.cpython-311.pyc | Bin 0 -> 7983 bytes .../__pycache__/easy_install.cpython-311.pyc | Bin 0 -> 121503 bytes .../editable_wheel.cpython-311.pyc | Bin 0 -> 51416 bytes .../__pycache__/egg_info.cpython-311.pyc | Bin 0 -> 40841 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 6818 bytes .../install_egg_info.cpython-311.pyc | Bin 0 -> 5344 bytes .../__pycache__/install_lib.cpython-311.pyc | Bin 0 -> 8415 bytes .../install_scripts.cpython-311.pyc | Bin 0 -> 4282 bytes .../__pycache__/py36compat.cpython-311.pyc | Bin 0 -> 8039 bytes .../__pycache__/register.cpython-311.pyc | Bin 0 -> 1129 bytes .../__pycache__/rotate.cpython-311.pyc | Bin 0 -> 4189 bytes .../__pycache__/saveopts.cpython-311.pyc | Bin 0 -> 1369 bytes .../command/__pycache__/sdist.cpython-311.pyc | Bin 0 -> 13441 bytes .../__pycache__/setopt.cpython-311.pyc | Bin 0 -> 7681 bytes .../command/__pycache__/test.cpython-311.pyc | Bin 0 -> 14622 bytes .../__pycache__/upload.cpython-311.pyc | Bin 0 -> 1093 bytes .../__pycache__/upload_docs.cpython-311.pyc | Bin 0 -> 11944 bytes .../site-packages/setuptools/command/alias.py | 78 + .../setuptools/command/bdist_egg.py | 457 + .../setuptools/command/bdist_rpm.py | 40 + .../site-packages/setuptools/command/build.py | 146 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 383 + .../setuptools/command/build_py.py | 368 + .../setuptools/command/develop.py | 193 + .../setuptools/command/dist_info.py | 142 + .../setuptools/command/easy_install.py | 2366 +++++ .../setuptools/command/editable_wheel.py | 844 ++ .../setuptools/command/egg_info.py | 775 ++ .../setuptools/command/install.py | 139 + .../setuptools/command/install_egg_info.py | 83 + .../setuptools/command/install_lib.py | 148 + .../setuptools/command/install_scripts.py | 70 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 134 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 64 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 210 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 251 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 212 + .../setuptools/config/__init__.py | 35 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2033 bytes .../_apply_pyprojecttoml.cpython-311.pyc | Bin 0 -> 22842 bytes .../config/__pycache__/expand.cpython-311.pyc | Bin 0 -> 28247 bytes .../__pycache__/pyprojecttoml.cpython-311.pyc | Bin 0 -> 27878 bytes .../__pycache__/setupcfg.cpython-311.pyc | Bin 0 -> 33287 bytes .../setuptools/config/_apply_pyprojecttoml.py | 384 + .../config/_validate_pyproject/__init__.py | 34 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2321 bytes .../error_reporting.cpython-311.pyc | Bin 0 -> 20212 bytes .../extra_validations.cpython-311.pyc | Bin 0 -> 1870 bytes .../fastjsonschema_exceptions.cpython-311.pyc | Bin 0 -> 3245 bytes ...fastjsonschema_validations.cpython-311.pyc | Bin 0 -> 192643 bytes .../__pycache__/formats.cpython-311.pyc | Bin 0 -> 14360 bytes .../_validate_pyproject/error_reporting.py | 318 + .../_validate_pyproject/extra_validations.py | 36 + .../fastjsonschema_exceptions.py | 51 + .../fastjsonschema_validations.py | 1035 ++ .../config/_validate_pyproject/formats.py | 259 + .../site-packages/setuptools/config/expand.py | 462 + .../setuptools/config/pyprojecttoml.py | 498 + .../setuptools/config/setupcfg.py | 769 ++ .../site-packages/setuptools/dep_util.py | 25 + .../site-packages/setuptools/depends.py | 176 + .../site-packages/setuptools/discovery.py | 601 ++ .../site-packages/setuptools/dist.py | 1218 +++ .../site-packages/setuptools/errors.py | 58 + .../site-packages/setuptools/extension.py | 148 + .../setuptools/extern/__init__.py | 76 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 4397 bytes .../site-packages/setuptools/glob.py | 167 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui-arm64.exe | Bin 0 -> 137728 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/installer.py | 104 + .../site-packages/setuptools/launch.py | 36 + .../site-packages/setuptools/logging.py | 37 + .../site-packages/setuptools/monkey.py | 165 + .../site-packages/setuptools/msvc.py | 1703 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1177 +++ .../site-packages/setuptools/py34compat.py | 13 + .../site-packages/setuptools/sandbox.py | 530 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/unicode_utils.py | 42 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 222 + .../setuptools/windows_support.py | 29 + .../sniffio-1.3.1.dist-info/INSTALLER | 1 + .../sniffio-1.3.1.dist-info/LICENSE | 3 + .../sniffio-1.3.1.dist-info/LICENSE.APACHE2 | 202 + .../sniffio-1.3.1.dist-info/LICENSE.MIT | 20 + .../sniffio-1.3.1.dist-info/METADATA | 104 + .../sniffio-1.3.1.dist-info/RECORD | 19 + .../sniffio-1.3.1.dist-info/WHEEL | 5 + .../sniffio-1.3.1.dist-info/top_level.txt | 1 + .../site-packages/sniffio/__init__.py | 17 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 540 bytes .../sniffio/__pycache__/_impl.cpython-311.pyc | Bin 0 -> 3404 bytes .../__pycache__/_version.cpython-311.pyc | Bin 0 -> 208 bytes .../python3.11/site-packages/sniffio/_impl.py | 95 + .../site-packages/sniffio/_tests/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 193 bytes .../__pycache__/test_sniffio.cpython-311.pyc | Bin 0 -> 5065 bytes .../sniffio/_tests/test_sniffio.py | 84 + .../site-packages/sniffio/_version.py | 3 + .../python3.11/site-packages/sniffio/py.typed | 0 .../starlette-0.46.1.dist-info/INSTALLER | 1 + .../starlette-0.46.1.dist-info/METADATA | 176 + .../starlette-0.46.1.dist-info/RECORD | 74 + .../starlette-0.46.1.dist-info/WHEEL | 4 + .../licenses/LICENSE.md | 27 + .../site-packages/starlette/__init__.py | 1 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 209 bytes .../_exception_handler.cpython-311.pyc | Bin 0 -> 3613 bytes .../__pycache__/_utils.cpython-311.pyc | Bin 0 -> 5873 bytes .../__pycache__/applications.cpython-311.pyc | Bin 0 -> 13853 bytes .../authentication.cpython-311.pyc | Bin 0 -> 9213 bytes .../__pycache__/background.cpython-311.pyc | Bin 0 -> 2952 bytes .../__pycache__/concurrency.cpython-311.pyc | Bin 0 -> 3703 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 8270 bytes .../__pycache__/convertors.cpython-311.pyc | Bin 0 -> 5781 bytes .../datastructures.cpython-311.pyc | Bin 0 -> 45716 bytes .../__pycache__/endpoints.cpython-311.pyc | Bin 0 -> 8707 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 2612 bytes .../__pycache__/formparsers.cpython-311.pyc | Bin 0 -> 15055 bytes .../__pycache__/requests.cpython-311.pyc | Bin 0 -> 17818 bytes .../__pycache__/responses.cpython-311.pyc | Bin 0 -> 32601 bytes .../__pycache__/routing.cpython-311.pyc | Bin 0 -> 48482 bytes .../__pycache__/schemas.cpython-311.pyc | Bin 0 -> 8050 bytes .../__pycache__/staticfiles.cpython-311.pyc | Bin 0 -> 12673 bytes .../__pycache__/status.cpython-311.pyc | Bin 0 -> 3658 bytes .../__pycache__/templating.cpython-311.pyc | Bin 0 -> 11102 bytes .../__pycache__/testclient.cpython-311.pyc | Bin 0 -> 35831 bytes .../__pycache__/types.cpython-311.pyc | Bin 0 -> 1684 bytes .../__pycache__/websockets.cpython-311.pyc | Bin 0 -> 12964 bytes .../starlette/_exception_handler.py | 65 + .../site-packages/starlette/_utils.py | 100 + .../site-packages/starlette/applications.py | 249 + .../site-packages/starlette/authentication.py | 147 + .../site-packages/starlette/background.py | 41 + .../site-packages/starlette/concurrency.py | 62 + .../site-packages/starlette/config.py | 138 + .../site-packages/starlette/convertors.py | 89 + .../site-packages/starlette/datastructures.py | 674 ++ .../site-packages/starlette/endpoints.py | 122 + .../site-packages/starlette/exceptions.py | 33 + .../site-packages/starlette/formparsers.py | 275 + .../starlette/middleware/__init__.py | 42 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3083 bytes .../authentication.cpython-311.pyc | Bin 0 -> 3253 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 12728 bytes .../__pycache__/cors.cpython-311.pyc | Bin 0 -> 8454 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 10663 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 4473 bytes .../__pycache__/gzip.cpython-311.pyc | Bin 0 -> 9359 bytes .../__pycache__/httpsredirect.cpython-311.pyc | Bin 0 -> 1952 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 0 -> 5035 bytes .../__pycache__/trustedhost.cpython-311.pyc | Bin 0 -> 3543 bytes .../__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 9696 bytes .../starlette/middleware/authentication.py | 52 + .../starlette/middleware/base.py | 220 + .../starlette/middleware/cors.py | 172 + .../starlette/middleware/errors.py | 260 + .../starlette/middleware/exceptions.py | 72 + .../starlette/middleware/gzip.py | 141 + .../starlette/middleware/httpsredirect.py | 19 + .../starlette/middleware/sessions.py | 85 + .../starlette/middleware/trustedhost.py | 60 + .../starlette/middleware/wsgi.py | 152 + .../site-packages/starlette/py.typed | 0 .../site-packages/starlette/requests.py | 322 + .../site-packages/starlette/responses.py | 536 + .../site-packages/starlette/routing.py | 874 ++ .../site-packages/starlette/schemas.py | 147 + .../site-packages/starlette/staticfiles.py | 220 + .../site-packages/starlette/status.py | 95 + .../site-packages/starlette/templating.py | 216 + .../site-packages/starlette/testclient.py | 731 ++ .../site-packages/starlette/types.py | 24 + .../site-packages/starlette/websockets.py | 195 + .../INSTALLER | 1 + .../METADATA | 68 + .../typing_extensions-4.13.0.dist-info/RECORD | 7 + .../typing_extensions-4.13.0.dist-info/WHEEL | 4 + .../licenses/LICENSE | 279 + .../site-packages/typing_extensions.py | 4566 +++++++++ .../INSTALLER | 1 + .../METADATA | 49 + .../typing_inspection-0.4.0.dist-info/RECORD | 13 + .../typing_inspection-0.4.0.dist-info/WHEEL | 4 + .../licenses/LICENSE | 21 + .../typing_inspection/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 196 bytes .../__pycache__/introspection.cpython-311.pyc | Bin 0 -> 18291 bytes .../typing_objects.cpython-311.pyc | Bin 0 -> 16754 bytes .../typing_inspection/introspection.py | 548 ++ .../site-packages/typing_inspection/py.typed | 0 .../typing_inspection/typing_objects.py | 582 ++ .../typing_inspection/typing_objects.pyi | 396 + .../uvicorn-0.34.0.dist-info/INSTALLER | 1 + .../uvicorn-0.34.0.dist-info/METADATA | 185 + .../uvicorn-0.34.0.dist-info/RECORD | 85 + .../uvicorn-0.34.0.dist-info/REQUESTED | 0 .../uvicorn-0.34.0.dist-info/WHEEL | 4 + .../uvicorn-0.34.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-311.pyc | Bin 0 -> 423 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 312 bytes .../__pycache__/_subprocess.cpython-311.pyc | Bin 0 -> 3100 bytes .../__pycache__/_types.cpython-311.pyc | Bin 0 -> 13640 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 26128 bytes .../__pycache__/importer.cpython-311.pyc | Bin 0 -> 2028 bytes .../__pycache__/logging.cpython-311.pyc | Bin 0 -> 8601 bytes .../uvicorn/__pycache__/main.cpython-311.pyc | Bin 0 -> 20429 bytes .../__pycache__/server.cpython-311.pyc | Bin 0 -> 16936 bytes .../__pycache__/workers.cpython-311.pyc | Bin 0 -> 6807 bytes .../site-packages/uvicorn/_subprocess.py | 84 + .../site-packages/uvicorn/_types.py | 281 + .../site-packages/uvicorn/config.py | 530 + .../site-packages/uvicorn/importer.py | 34 + .../uvicorn/lifespan/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 195 bytes .../lifespan/__pycache__/off.cpython-311.pyc | Bin 0 -> 1150 bytes .../lifespan/__pycache__/on.cpython-311.pyc | Bin 0 -> 8381 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-311.pyc | Bin 0 -> 192 bytes .../loops/__pycache__/asyncio.cpython-311.pyc | Bin 0 -> 811 bytes .../loops/__pycache__/auto.cpython-311.pyc | Bin 0 -> 782 bytes .../loops/__pycache__/uvloop.cpython-311.pyc | Bin 0 -> 585 bytes .../site-packages/uvicorn/loops/asyncio.py | 10 + .../site-packages/uvicorn/loops/auto.py | 11 + .../site-packages/uvicorn/loops/uvloop.py | 7 + .../python3.11/site-packages/uvicorn/main.py | 591 ++ .../uvicorn/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 197 bytes .../__pycache__/asgi2.cpython-311.pyc | Bin 0 -> 1214 bytes .../message_logger.cpython-311.pyc | Bin 0 -> 4900 bytes .../__pycache__/proxy_headers.cpython-311.pyc | Bin 0 -> 6687 bytes .../__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 10906 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 | 200 + .../uvicorn/protocols/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 196 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 3561 bytes .../uvicorn/protocols/http/__init__.py | 0 .../http/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 201 bytes .../http/__pycache__/auto.cpython-311.pyc | Bin 0 -> 700 bytes .../__pycache__/flow_control.cpython-311.pyc | Bin 0 -> 3297 bytes .../http/__pycache__/h11_impl.cpython-311.pyc | Bin 0 -> 27816 bytes .../httptools_impl.cpython-311.pyc | Bin 0 -> 30350 bytes .../uvicorn/protocols/http/auto.py | 15 + .../uvicorn/protocols/http/flow_control.py | 54 + .../uvicorn/protocols/http/h11_impl.py | 543 ++ .../uvicorn/protocols/http/httptools_impl.py | 570 ++ .../site-packages/uvicorn/protocols/utils.py | 56 + .../uvicorn/protocols/websockets/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 207 bytes .../__pycache__/auto.cpython-311.pyc | Bin 0 -> 919 bytes .../websockets_impl.cpython-311.pyc | Bin 0 -> 22390 bytes .../__pycache__/wsproto_impl.cpython-311.pyc | Bin 0 -> 22397 bytes .../uvicorn/protocols/websockets/auto.py | 21 + .../protocols/websockets/websockets_impl.py | 386 + .../protocols/websockets/wsproto_impl.py | 377 + .../python3.11/site-packages/uvicorn/py.typed | 1 + .../site-packages/uvicorn/server.py | 337 + .../uvicorn/supervisors/__init__.py | 16 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 886 bytes .../__pycache__/basereload.cpython-311.pyc | Bin 0 -> 7363 bytes .../__pycache__/multiprocess.cpython-311.pyc | Bin 0 -> 14649 bytes .../__pycache__/statreload.cpython-311.pyc | Bin 0 -> 3272 bytes .../watchfilesreload.cpython-311.pyc | Bin 0 -> 5549 bytes .../uvicorn/supervisors/basereload.py | 122 + .../uvicorn/supervisors/multiprocess.py | 222 + .../uvicorn/supervisors/statreload.py | 53 + .../uvicorn/supervisors/watchfilesreload.py | 88 + .../site-packages/uvicorn/workers.py | 114 + venv/lib64 | 1 + venv/pyvenv.cfg | 5 + 2312 files changed, 422700 insertions(+) create mode 100644 __pycache__/main.cpython-311.pyc create mode 100644 main.py create mode 100644 static/app.js create mode 100644 static/emoji.js create mode 100644 static/index.html create mode 100644 static/ollama.js create mode 100644 static/style.css 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/pip create mode 100755 venv/bin/pip3 create mode 100755 venv/bin/pip3.11 create mode 120000 venv/bin/python create mode 120000 venv/bin/python3 create mode 120000 venv/bin/python3.11 create mode 100755 venv/bin/uvicorn create mode 100644 venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/__pycache__/typing_extensions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/_distutils_hack/__init__.py create mode 100644 venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/override.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/_distutils_hack/override.py create mode 100644 venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.11/site-packages/annotated_types/__init__.py create mode 100644 venv/lib/python3.11/site-packages/annotated_types/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/annotated_types/__pycache__/test_cases.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/annotated_types/py.typed create mode 100644 venv/lib/python3.11/site-packages/annotated_types/test_cases.py create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/LICENSE create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/anyio/__init__.py create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/from_thread.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/lowlevel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/pytest_plugin.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/to_interpreter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/to_process.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/__pycache__/to_thread.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_backends/__init__.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/_trio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_backends/_trio.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__init__.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_asyncio_selector_thread.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_eventloop.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_fileio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_resources.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_signals.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_sockets.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_streams.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_subprocesses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_synchronization.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_tasks.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_tempfile.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_typedattr.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_asyncio_selector_thread.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_eventloop.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_exceptions.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_fileio.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_resources.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_signals.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_sockets.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_streams.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_subprocesses.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_synchronization.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_tasks.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_tempfile.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_testing.py create mode 100644 venv/lib/python3.11/site-packages/anyio/_core/_typedattr.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__init__.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_eventloop.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_resources.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_sockets.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_streams.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_tasks.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_eventloop.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_resources.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_sockets.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_streams.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_subprocesses.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_tasks.py create mode 100644 venv/lib/python3.11/site-packages/anyio/abc/_testing.py create mode 100644 venv/lib/python3.11/site-packages/anyio/from_thread.py create mode 100644 venv/lib/python3.11/site-packages/anyio/lowlevel.py create mode 100644 venv/lib/python3.11/site-packages/anyio/py.typed create mode 100644 venv/lib/python3.11/site-packages/anyio/pytest_plugin.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__init__.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/buffered.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/file.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/memory.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/stapled.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/text.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/__pycache__/tls.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/buffered.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/file.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/memory.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/stapled.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/text.py create mode 100644 venv/lib/python3.11/site-packages/anyio/streams/tls.py create mode 100644 venv/lib/python3.11/site-packages/anyio/to_interpreter.py create mode 100644 venv/lib/python3.11/site-packages/anyio/to_process.py create mode 100644 venv/lib/python3.11/site-packages/anyio/to_thread.py create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/LICENSE create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/bcrypt/__init__.py create mode 100644 venv/lib/python3.11/site-packages/bcrypt/__init__.pyi create mode 100644 venv/lib/python3.11/site-packages/bcrypt/__pycache__/__init__.cpython-311.pyc create mode 100755 venv/lib/python3.11/site-packages/bcrypt/_bcrypt.abi3.so create mode 100644 venv/lib/python3.11/site-packages/bcrypt/py.typed create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/click/__init__.py create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_termui_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_textwrap.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_winconsole.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/decorators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/formatting.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/globals.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/shell_completion.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/termui.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/_compat.py create mode 100644 venv/lib/python3.11/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python3.11/site-packages/click/_textwrap.py create mode 100644 venv/lib/python3.11/site-packages/click/_winconsole.py create mode 100644 venv/lib/python3.11/site-packages/click/core.py create mode 100644 venv/lib/python3.11/site-packages/click/decorators.py create mode 100644 venv/lib/python3.11/site-packages/click/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/click/formatting.py create mode 100644 venv/lib/python3.11/site-packages/click/globals.py create mode 100644 venv/lib/python3.11/site-packages/click/parser.py create mode 100644 venv/lib/python3.11/site-packages/click/py.typed create mode 100644 venv/lib/python3.11/site-packages/click/shell_completion.py create mode 100644 venv/lib/python3.11/site-packages/click/termui.py create mode 100644 venv/lib/python3.11/site-packages/click/testing.py create mode 100644 venv/lib/python3.11/site-packages/click/types.py create mode 100644 venv/lib/python3.11/site-packages/click/utils.py create mode 100644 venv/lib/python3.11/site-packages/distutils-precedence.pth create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/entry_points.txt create mode 100644 venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.11/site-packages/fastapi/__init__.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/__main__.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/applications.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/background.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/cli.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/concurrency.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/datastructures.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/encoders.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/exception_handlers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/logger.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/param_functions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/params.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/requests.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/responses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/routing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/staticfiles.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/templating.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/testclient.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/__pycache__/websockets.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/_compat.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/applications.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/background.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/cli.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/concurrency.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/datastructures.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/dependencies/__init__.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/models.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/dependencies/models.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/dependencies/utils.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/encoders.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/exception_handlers.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/logger.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__init__.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/cors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/gzip.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/cors.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/gzip.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/httpsredirect.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/trustedhost.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/middleware/wsgi.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/__init__.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/constants.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/docs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/models.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/constants.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/docs.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/models.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/openapi/utils.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/param_functions.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/params.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/py.typed create mode 100644 venv/lib/python3.11/site-packages/fastapi/requests.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/responses.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/routing.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__init__.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/api_key.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/http.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/oauth2.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/api_key.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/base.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/http.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/oauth2.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/open_id_connect_url.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/security/utils.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/staticfiles.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/templating.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/testclient.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/types.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/utils.py create mode 100644 venv/lib/python3.11/site-packages/fastapi/websockets.py create mode 100644 venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/h11/__init__.py create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_abnf.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_connection.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_events.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_headers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_readers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_receivebuffer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_state.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/__pycache__/_writers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/_abnf.py create mode 100644 venv/lib/python3.11/site-packages/h11/_connection.py create mode 100644 venv/lib/python3.11/site-packages/h11/_events.py create mode 100644 venv/lib/python3.11/site-packages/h11/_headers.py create mode 100644 venv/lib/python3.11/site-packages/h11/_readers.py create mode 100644 venv/lib/python3.11/site-packages/h11/_receivebuffer.py create mode 100644 venv/lib/python3.11/site-packages/h11/_state.py create mode 100644 venv/lib/python3.11/site-packages/h11/_util.py create mode 100644 venv/lib/python3.11/site-packages/h11/_version.py create mode 100644 venv/lib/python3.11/site-packages/h11/_writers.py create mode 100644 venv/lib/python3.11/site-packages/h11/py.typed create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__init__.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/helpers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_against_stdlib_http.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_connection.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_events.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_headers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_helpers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_io.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_state.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/h11/tests/data/test-file create mode 100644 venv/lib/python3.11/site-packages/h11/tests/helpers.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_against_stdlib_http.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_connection.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_events.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_headers.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_helpers.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_io.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_receivebuffer.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_state.py create mode 100644 venv/lib/python3.11/site-packages/h11/tests/test_util.py create mode 100644 venv/lib/python3.11/site-packages/idna-3.10.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/idna-3.10.dist-info/LICENSE.md create mode 100644 venv/lib/python3.11/site-packages/idna-3.10.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/idna-3.10.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/idna-3.10.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/idna/__init__.py create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/codec.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/idnadata.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/intranges.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/package_data.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/__pycache__/uts46data.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/idna/codec.py create mode 100644 venv/lib/python3.11/site-packages/idna/compat.py create mode 100644 venv/lib/python3.11/site-packages/idna/core.py create mode 100644 venv/lib/python3.11/site-packages/idna/idnadata.py create mode 100644 venv/lib/python3.11/site-packages/idna/intranges.py create mode 100644 venv/lib/python3.11/site-packages/idna/package_data.py create mode 100644 venv/lib/python3.11/site-packages/idna/py.typed create mode 100644 venv/lib/python3.11/site-packages/idna/uts46data.py create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/entry_points.txt create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/jinja2/__init__.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/_identifier.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/async_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/bccache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/constants.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/debug.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/defaults.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/environment.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/ext.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/filters.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/idtracking.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/lexer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/loaders.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/meta.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/nativetypes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/nodes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/optimizer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/runtime.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/sandbox.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/tests.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/__pycache__/visitor.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/jinja2/_identifier.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/async_utils.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/bccache.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/compiler.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/constants.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/debug.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/defaults.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/environment.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/ext.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/filters.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/idtracking.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/lexer.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/loaders.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/meta.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/nativetypes.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/nodes.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/optimizer.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/parser.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/py.typed create mode 100644 venv/lib/python3.11/site-packages/jinja2/runtime.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/sandbox.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/tests.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/utils.py create mode 100644 venv/lib/python3.11/site-packages/jinja2/visitor.py create mode 100644 venv/lib/python3.11/site-packages/markupsafe/__init__.py create mode 100644 venv/lib/python3.11/site-packages/markupsafe/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/markupsafe/__pycache__/_native.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/markupsafe/_native.py create mode 100644 venv/lib/python3.11/site-packages/markupsafe/_speedups.c create mode 100755 venv/lib/python3.11/site-packages/markupsafe/_speedups.cpython-311-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.11/site-packages/markupsafe/_speedups.pyi create mode 100644 venv/lib/python3.11/site-packages/markupsafe/py.typed create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.11/site-packages/pip-23.0.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/pip/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pip/__pip-runner__.py create mode 100644 venv/lib/python3.11/site-packages/pip/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/__pycache__/__pip-runner__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/build_env.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/cache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/configuration.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/main.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/pyproject.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/build_env.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cache.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/main.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/command_context.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/main.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/req_command.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/spinners.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/cache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/check.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/completion.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/debug.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/download.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/hash.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/help.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/index.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/install.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/list.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/search.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/show.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/cache.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/check.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/debug.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/download.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/help.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/index.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/inspect.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/install.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/list.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/search.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/show.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/configuration.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/base.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/installed.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/sdist.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/distributions/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/collector.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/__pycache__/sources.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/collector.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/package_finder.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/index/sources.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/_distutils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/locations/base.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/main.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/_json.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/base.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/candidate.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/format_control.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/index.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/link.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/scheme.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/target_python.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/direct_url.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/index.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/installation_report.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/link.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/scheme.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/search_scope.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/target_python.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/models/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/auth.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/cache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/download.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/session.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/auth.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/cache.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/download.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/session.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/utils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/check.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/check.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/pyproject.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/constructors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_file.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_install.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_set.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/base.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/self_outdated_check.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/_log.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/logging.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/misc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/models.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/urls.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/_log.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/datetime.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/egg_link.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/filetypes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/models.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/subprocess.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/unpacking.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/urls.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/utils/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/git.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 venv/lib/python3.11/site-packages/pip/_internal/wheel_builder.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/six.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/codingstatemachinedict.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/enums.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/johabfreq.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/johabprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/macromanprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/resultdict.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/utf1632prober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/chardet/version.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/ansi_test.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/ansitowin32_test.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/initialise_test.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/isatty_test.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/utils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/tests/winterm_test.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/win32.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distro/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distro/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/distro/distro.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/codec.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/core.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/intranges.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/package_data.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/tags.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/console.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/filter.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/style.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/token.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pygments/util.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_impl.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/api.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/help.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/models.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/__version__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/help.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/packages.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/align.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/box.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/color.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/console.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/control.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/json.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/live.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/region.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/status.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/style.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/table.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/text.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_export_format.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_extension.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_loop.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_null_file.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_pick.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_stack.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_timer.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_windows.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/abc.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/align.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/ansi.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/bar.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/box.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/cells.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/color.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/columns.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/console.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/constrain.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/containers.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/control.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/emoji.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/errors.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/filesize.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/json.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/layout.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/live.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/live_render.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/logging.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/markup.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/measure.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/padding.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/pager.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/palette.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/panel.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/pretty.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/progress.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/prompt.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/protocol.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/region.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/repr.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/rule.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/scope.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/screen.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/segment.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/spinner.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/status.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/style.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/styled.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/syntax.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/table.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/text.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/theme.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/themes.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/traceback.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/rich/tree.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/six.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/after.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/before.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/_re.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/tomli/_types.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/typing_extensions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/request.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/response.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/vendor.txt create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 venv/lib/python3.11/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 venv/lib/python3.11/site-packages/pip/py.typed create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/__pycache__/typing_extensions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/__pycache__/zipp.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_adapters.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_common.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_itertools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_legacy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/abc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/readers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/simple.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/_adapters.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/_common.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/_compat.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/_itertools.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/_legacy.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/abc.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/readers.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/importlib_resources/simple.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/__pycache__/context.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/__pycache__/functools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/context.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/functools.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/text/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/jaraco/text/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/more_itertools/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/more.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/recipes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/more_itertools/more.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/more_itertools/recipes.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/_manylinux.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/_musllinux.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/_manylinux.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/_musllinux.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__main__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/android.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/api.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/macos.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/unix.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/__pycache__/windows.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/android.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/api.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/macos.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/unix.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/version.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/platformdirs/windows.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/actions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/common.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/helpers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/results.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/unicode.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/actions.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/common.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/core.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/diagram/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/helpers.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/results.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/testing.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/unicode.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/pyparsing/util.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/typing_extensions.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/_vendor/zipp.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/extern/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic-2.11.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/pydantic-2.11.1.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/pydantic-2.11.1.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/pydantic-2.11.1.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/pydantic-2.11.1.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.11/site-packages/pydantic/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/_migration.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/alias_generators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/aliases.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/annotated_handlers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/class_validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/color.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/dataclasses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/datetime_parse.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/decorator.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/env_settings.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/error_wrappers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/errors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/fields.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/functional_serializers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/functional_validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/generics.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/json.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/json_schema.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/main.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/mypy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/networks.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/parse.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/root_model.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/schema.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/tools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/type_adapter.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/typing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/validate_call_decorator.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/__pycache__/warnings.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_core_metadata.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_core_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_dataclasses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_decorators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_decorators_v1.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_discriminated_union.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_docs_extraction.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_fields.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_forward_ref.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_generics.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_git.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_import_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_internal_dataclass.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_known_annotated_metadata.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_mock_val_ser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_model_construction.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_namespace_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_repr.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_schema_gather.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_schema_generation_shared.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_serializers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_signature.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_typing_extra.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_validate_call.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/__pycache__/_validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_config.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_core_metadata.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_core_utils.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_dataclasses.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_decorators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_decorators_v1.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_discriminated_union.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_docs_extraction.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_fields.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_forward_ref.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_generate_schema.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_generics.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_git.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_import_utils.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_internal_dataclass.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_known_annotated_metadata.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_mock_val_ser.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_model_construction.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_namespace_utils.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_repr.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_schema_gather.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_schema_generation_shared.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_serializers.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_signature.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_typing_extra.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_utils.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_validate_call.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_internal/_validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/_migration.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/alias_generators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/aliases.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/annotated_handlers.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/class_validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/color.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/config.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/dataclasses.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/datetime_parse.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/decorator.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/class_validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/copy_internals.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/decorator.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/json.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/parse.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/__pycache__/tools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/class_validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/config.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/copy_internals.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/decorator.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/json.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/parse.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/deprecated/tools.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/env_settings.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/error_wrappers.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/errors.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/experimental/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/experimental/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/experimental/__pycache__/arguments_schema.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/experimental/__pycache__/pipeline.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/experimental/arguments_schema.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/experimental/pipeline.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/fields.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/functional_serializers.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/functional_validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/generics.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/json.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/json_schema.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/main.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/mypy.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/networks.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/parse.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/plugin/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/plugin/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/plugin/__pycache__/_loader.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/plugin/__pycache__/_schema_validator.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/plugin/_loader.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/plugin/_schema_validator.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/py.typed create mode 100644 venv/lib/python3.11/site-packages/pydantic/root_model.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/schema.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/tools.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/type_adapter.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/types.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/typing.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/utils.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/_hypothesis_plugin.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/annotated_types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/class_validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/color.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/dataclasses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/datetime_parse.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/decorator.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/env_settings.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/error_wrappers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/errors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/fields.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/generics.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/json.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/main.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/mypy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/networks.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/parse.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/schema.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/tools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/typing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/validators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/_hypothesis_plugin.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/annotated_types.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/class_validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/color.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/config.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/dataclasses.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/datetime_parse.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/decorator.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/env_settings.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/error_wrappers.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/errors.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/fields.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/generics.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/json.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/main.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/mypy.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/networks.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/parse.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/py.typed create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/schema.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/tools.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/types.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/typing.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/utils.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/v1/version.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/validate_call_decorator.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/validators.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/version.py create mode 100644 venv/lib/python3.11/site-packages/pydantic/warnings.py create mode 100644 venv/lib/python3.11/site-packages/pydantic_core-2.33.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/pydantic_core-2.33.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/pydantic_core-2.33.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/pydantic_core-2.33.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/pydantic_core-2.33.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.11/site-packages/pydantic_core/__init__.py create mode 100644 venv/lib/python3.11/site-packages/pydantic_core/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/pydantic_core/__pycache__/core_schema.cpython-311.pyc create mode 100755 venv/lib/python3.11/site-packages/pydantic_core/_pydantic_core.cpython-311-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.11/site-packages/pydantic_core/_pydantic_core.pyi create mode 100644 venv/lib/python3.11/site-packages/pydantic_core/core_schema.py create mode 100644 venv/lib/python3.11/site-packages/pydantic_core/py.typed create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/LICENSE create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.11/site-packages/setuptools-66.1.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/setuptools/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_entry_points.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_imp.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_importlib.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_itertools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_path.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/_reqs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/archive_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/build_meta.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/dep_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/depends.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/discovery.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/dist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/errors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/extension.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/glob.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/installer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/launch.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/logging.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/monkey.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/msvc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/namespaces.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/package_index.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/py34compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/sandbox.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/unicode_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/__pycache__/windows_support.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_deprecation_warning.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/_collections.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/_functools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/_log.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/_macos_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/debug.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/dist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/errors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/extension.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/log.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/py39compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/_collections.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/_functools.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/_log.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/_macos_compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/archive_util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/cmd.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/_framework_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/_framework_compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/build.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/check.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/clean.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/config.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/install.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/register.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/command/upload.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/config.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/core.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/debug.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/dep_util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/dir_util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/dist.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/errors.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/extension.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/file_util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/filelist.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/log.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/py38compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/py39compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/spawn.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/text_file.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/version.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_entry_points.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_imp.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_importlib.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_itertools.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_path.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_reqs.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/__pycache__/typing_extensions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/__pycache__/zipp.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_adapters.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_collections.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_functools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_itertools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_meta.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_text.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_adapters.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_collections.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_functools.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_itertools.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_meta.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_metadata/_text.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_adapters.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_common.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_itertools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_legacy.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/abc.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/readers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/__pycache__/simple.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/_adapters.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/_common.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/_compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/_itertools.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/_legacy.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/abc.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/readers.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/importlib_resources/simple.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/__pycache__/context.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/__pycache__/functools.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/context.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/functools.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/text/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/jaraco/text/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/more.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/more_itertools/recipes.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/_manylinux.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/_musllinux.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/actions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/common.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/helpers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/results.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/unicode.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/__pycache__/util.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/actions.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/common.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/core.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/diagram/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/helpers.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/results.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/testing.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/unicode.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/pyparsing/util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/__pycache__/_parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/__pycache__/_re.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/__pycache__/_types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/_parser.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/_re.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/tomli/_types.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/typing_extensions.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/_vendor/zipp.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/archive_util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/build_meta.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/cli-32.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/cli-64.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/cli-arm64.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/cli.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/alias.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/build.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/build_clib.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/build_ext.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/build_py.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/develop.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/dist_info.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/easy_install.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/editable_wheel.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/egg_info.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/install.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/install_lib.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/install_scripts.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/py36compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/register.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/rotate.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/saveopts.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/sdist.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/setopt.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/test.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/upload.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/__pycache__/upload_docs.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/alias.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/bdist_egg.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/bdist_rpm.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/build.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/build_clib.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/build_ext.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/build_py.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/develop.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/dist_info.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/easy_install.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/editable_wheel.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/egg_info.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/install.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/install_egg_info.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/install_lib.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/install_scripts.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/launcher manifest.xml create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/py36compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/register.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/rotate.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/saveopts.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/sdist.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/setopt.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/test.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/upload.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/command/upload_docs.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/__pycache__/_apply_pyprojecttoml.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/__pycache__/expand.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/__pycache__/pyprojecttoml.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/__pycache__/setupcfg.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_apply_pyprojecttoml.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__pycache__/error_reporting.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__pycache__/extra_validations.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_validations.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/__pycache__/formats.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/error_reporting.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/extra_validations.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_validations.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/_validate_pyproject/formats.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/expand.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/config/setupcfg.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/dep_util.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/depends.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/discovery.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/dist.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/errors.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/extension.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/extern/__init__.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/extern/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/setuptools/glob.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/gui-32.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/gui-64.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/gui-arm64.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/gui.exe create mode 100644 venv/lib/python3.11/site-packages/setuptools/installer.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/launch.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/logging.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/monkey.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/msvc.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/namespaces.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/package_index.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/py34compat.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/sandbox.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/script (dev).tmpl create mode 100644 venv/lib/python3.11/site-packages/setuptools/script.tmpl create mode 100644 venv/lib/python3.11/site-packages/setuptools/unicode_utils.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/version.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/wheel.py create mode 100644 venv/lib/python3.11/site-packages/setuptools/windows_support.py create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/LICENSE create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/LICENSE.APACHE2 create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/LICENSE.MIT create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/sniffio-1.3.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.11/site-packages/sniffio/__init__.py create mode 100644 venv/lib/python3.11/site-packages/sniffio/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/sniffio/__pycache__/_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/sniffio/__pycache__/_version.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/sniffio/_impl.py create mode 100644 venv/lib/python3.11/site-packages/sniffio/_tests/__init__.py create mode 100644 venv/lib/python3.11/site-packages/sniffio/_tests/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/sniffio/_tests/__pycache__/test_sniffio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/sniffio/_tests/test_sniffio.py create mode 100644 venv/lib/python3.11/site-packages/sniffio/_version.py create mode 100644 venv/lib/python3.11/site-packages/sniffio/py.typed create mode 100644 venv/lib/python3.11/site-packages/starlette-0.46.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/starlette-0.46.1.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/starlette-0.46.1.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/starlette-0.46.1.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/starlette-0.46.1.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.11/site-packages/starlette/__init__.py create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/_exception_handler.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/_utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/applications.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/authentication.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/background.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/concurrency.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/convertors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/datastructures.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/endpoints.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/formparsers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/requests.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/responses.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/routing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/schemas.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/staticfiles.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/status.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/templating.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/testclient.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/__pycache__/websockets.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/_exception_handler.py create mode 100644 venv/lib/python3.11/site-packages/starlette/_utils.py create mode 100644 venv/lib/python3.11/site-packages/starlette/applications.py create mode 100644 venv/lib/python3.11/site-packages/starlette/authentication.py create mode 100644 venv/lib/python3.11/site-packages/starlette/background.py create mode 100644 venv/lib/python3.11/site-packages/starlette/concurrency.py create mode 100644 venv/lib/python3.11/site-packages/starlette/config.py create mode 100644 venv/lib/python3.11/site-packages/starlette/convertors.py create mode 100644 venv/lib/python3.11/site-packages/starlette/datastructures.py create mode 100644 venv/lib/python3.11/site-packages/starlette/endpoints.py create mode 100644 venv/lib/python3.11/site-packages/starlette/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/starlette/formparsers.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__init__.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/authentication.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/base.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/cors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/errors.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/gzip.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/httpsredirect.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/sessions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/trustedhost.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/__pycache__/wsgi.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/authentication.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/base.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/cors.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/errors.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/gzip.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/httpsredirect.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/sessions.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/trustedhost.py create mode 100644 venv/lib/python3.11/site-packages/starlette/middleware/wsgi.py create mode 100644 venv/lib/python3.11/site-packages/starlette/py.typed create mode 100644 venv/lib/python3.11/site-packages/starlette/requests.py create mode 100644 venv/lib/python3.11/site-packages/starlette/responses.py create mode 100644 venv/lib/python3.11/site-packages/starlette/routing.py create mode 100644 venv/lib/python3.11/site-packages/starlette/schemas.py create mode 100644 venv/lib/python3.11/site-packages/starlette/staticfiles.py create mode 100644 venv/lib/python3.11/site-packages/starlette/status.py create mode 100644 venv/lib/python3.11/site-packages/starlette/templating.py create mode 100644 venv/lib/python3.11/site-packages/starlette/testclient.py create mode 100644 venv/lib/python3.11/site-packages/starlette/types.py create mode 100644 venv/lib/python3.11/site-packages/starlette/websockets.py create mode 100644 venv/lib/python3.11/site-packages/typing_extensions-4.13.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/typing_extensions-4.13.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/typing_extensions-4.13.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/typing_extensions-4.13.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/typing_extensions-4.13.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.11/site-packages/typing_extensions.py create mode 100644 venv/lib/python3.11/site-packages/typing_inspection-0.4.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/typing_inspection-0.4.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/typing_inspection-0.4.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/typing_inspection-0.4.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/typing_inspection-0.4.0.dist-info/licenses/LICENSE create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/__init__.py create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/__pycache__/introspection.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/__pycache__/typing_objects.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/introspection.py create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/py.typed create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/typing_objects.py create mode 100644 venv/lib/python3.11/site-packages/typing_inspection/typing_objects.pyi create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.11/site-packages/uvicorn-0.34.0.dist-info/licenses/LICENSE.md create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__main__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/__main__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/_subprocess.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/_types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/config.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/importer.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/logging.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/main.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/server.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/__pycache__/workers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/_subprocess.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/_types.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/config.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/importer.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/lifespan/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/off.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/lifespan/__pycache__/on.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/lifespan/off.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/lifespan/on.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/logging.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/__pycache__/asyncio.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/__pycache__/auto.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/__pycache__/uvloop.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/asyncio.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/auto.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/loops/uvloop.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/main.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/__pycache__/asgi2.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/__pycache__/message_logger.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/__pycache__/proxy_headers.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/__pycache__/wsgi.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/asgi2.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/message_logger.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/middleware/wsgi.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/__pycache__/auto.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/__pycache__/flow_control.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/__pycache__/h11_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/__pycache__/httptools_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/auto.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/flow_control.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/h11_impl.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/utils.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/__pycache__/auto.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/__pycache__/websockets_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/auto.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/websockets_impl.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/protocols/websockets/wsproto_impl.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/py.typed create mode 100644 venv/lib/python3.11/site-packages/uvicorn/server.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/__init__.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/__pycache__/basereload.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/__pycache__/multiprocess.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/__pycache__/statreload.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/__pycache__/watchfilesreload.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/basereload.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/multiprocess.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/statreload.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/supervisors/watchfilesreload.py create mode 100644 venv/lib/python3.11/site-packages/uvicorn/workers.py create mode 120000 venv/lib64 create mode 100644 venv/pyvenv.cfg diff --git a/__pycache__/main.cpython-311.pyc b/__pycache__/main.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd0cf12e64b605032af6af04aa5e02fb0c95d6a1 GIT binary patch literal 1883 zcmZux-D?|15Z}E!=}tPy@&~Tm+HsURlqx3DLyYZ$DRykqFWWU$3PmX#7wuZUw*y}Mgm^Y zqlQ=%4XG#vazu|A@nRe!4pF=ZE}wM#qoPdZ-Ndoj#gHgi^F-X2_Tb-7V1x};VtYKS zzz7@j`wk-UEktA*KdCDw!GBN3vU?^8D(xrtIPe4`Y@}xkojP9%_V;%5-7`s@I#(}E zu5zSrOE~4BkMtK%cHl3zIg5Sqnrb_9EAIg-7aY~mO4l@<+8_!msFX>Blv71f}n?n8GlJA4CH zA0dj0n4lu}F(6HaSC1`egy0#F2nQ$U{oWO~R?}(0y=iE+t(g^HvgsX{R!Vd^8}%hc zVLwt7KdvZ-NnD-r2}QZ%s(M=^=$h^LyzN+iN>S8G#bhUk02SpiI%GdSI-kF*TKV<$ z^*lAqTN=G<>Mk?M8>&{xRX408SOtXT!+sq|z3V&Z>EFKcQ1gT|^hQ8|v0mwHI>LE? zq{nLGs+4rqw$Fg`C72&B0{H-80LVEmI{*WpO!#h>4mPwK;r98Hb^xKUTJX>gW$S<@Js=*PnZoH)%x;kRm+#wXzBLlYLHn! zZXf5i)EySQ2PlAq024y;8M+00*vbIP_xN^jf2=;IQ(d4W9O1Q7fECaw3*oFqHnN=M zUH047cRQOM=Ib`|!_R&c66orV%ifINzWFLsa7!g>+ZWssw(#x4%ynxcGgpR^$-KF^ zxRilH%eXcrS-_UP16CAB7F(k**(}tI6#$zE@K8cLtP7xE%k~105Zji7r2eM(nm0Nb z_GjXxCr&<34exxi`?)tV*+@+_Q&XNa^;}Nx40&U7-q6*CJl~Y(Jz+jTemUFki>q+` z0e_2u?N>R^uAby$3WL^h6T~rvFntt9mHXY%v7pw5VZmii6t?SSF2S& zVwi5l32uwem#Gs}i!W47xPdIVQ+0JD&4d^CZEGB~3>W(?pe-I_43Xmz4-I$s12pcP z><4JbJJ}D=wD*7g0F8Pl`>)Ytz5Io?rPcXX6k*|hY%}&CyM1H(#!u7U;6!6^qB%J6 zbh;jEpoJz{@X$glit$hjoh92FFWBloFI7>*Mee6J(+>uAKCP!4_)-&JYH=9PVYYt` tzu*x!{&FoaAKD!9;^!K8w24PsTm&y*Z|q77F{Ycct>=$Tx-~(*{{vUrzg++T literal 0 HcmV?d00001 diff --git a/main.py b/main.py new file mode 100644 index 0000000..8697fcf --- /dev/null +++ b/main.py @@ -0,0 +1,30 @@ +# main.py +# FastAPI backend for Emoji Evolution – placeholder logic for LLM override + +from fastapi import FastAPI +from fastapi.staticfiles import StaticFiles +from pathlib import Path +from fastapi.responses import JSONResponse, HTMLResponse +from pydantic import BaseModel + +app = FastAPI() + +# Mount the 'static' directory to serve frontend files +app.mount("/static", StaticFiles(directory="static"), name="static") + +# Pydantic model for puzzle submission +class PuzzleSubmission(BaseModel): + sequence: list[str] + +@app.get("/", response_class=HTMLResponse) +async def root_html(): + return Path("static/index.html").read_text(encoding="utf-8") + +@app.post("/api/check-puzzle") +async def check_puzzle(submission: PuzzleSubmission): + # Server-side logic is now obsolete (replaced by LLM check in frontend) + # Keeping this route for local fallback/testing if needed + if submission.sequence == ["😂", "😊", "🥳"]: + return JSONResponse({"result": "✅ Success!"}) + return JSONResponse({"result": "❌ Try Again (LLM not used)"}) + diff --git a/static/app.js b/static/app.js new file mode 100644 index 0000000..3b5cf3c --- /dev/null +++ b/static/app.js @@ -0,0 +1,71 @@ +import { ALL_EMOJIS } from './emoji.js'; +import { checkWithOllama } from './ollama.js'; + +document.addEventListener("DOMContentLoaded", () => { + const slots = document.querySelectorAll(".emoji-slot"); + const emojiBank = document.getElementById("emoji-bank"); + const resetBtn = document.getElementById("reset-btn"); + const feedback = document.getElementById("feedback"); + + const allEmojis = ALL_EMOJIS; + const selectedEmojis = allEmojis.sort(() => 0.5 - Math.random()).slice(0, 9); + + // Fill emoji bank with shuffled emojis + selectedEmojis.forEach(emoji => { + const span = document.createElement("span"); + span.className = "emoji"; + span.textContent = emoji; + span.draggable = true; + span.addEventListener("dragstart", (e) => { + e.dataTransfer.setData("text", e.target.textContent); + }); + emojiBank.appendChild(span); + }); + + // Drag and Drop Setup (emoji drag already handled inline) + + slots.forEach(slot => { + slot.addEventListener("dragover", (e) => e.preventDefault()); + slot.addEventListener("drop", (e) => { + e.preventDefault(); + const emoji = e.dataTransfer.getData("text"); + slot.textContent = emoji; + saveSequence(); + checkPuzzle(); + }); + }); + + // Auto-check puzzle when a drop occurs + async function checkPuzzle() { + const sequence = Array.from(slots).map(slot => slot.textContent || ""); + + + + feedback.textContent = "⌛ Checking your solution..."; + + try { + const result = await checkWithOllama(sequence); + feedback.innerHTML = result + .split("\n") + .map(line => `${line}`) + .join("
"); + } catch (err) { + feedback.textContent = "❌ Error while checking the puzzle."; + console.error(err); + } + } + + // Reset Puzzle + resetBtn.addEventListener("click", () => { + slots.forEach(slot => slot.textContent = ""); + localStorage.removeItem("emojiSequence"); + feedback.textContent = ""; + }); + + // Save sequence to localStorage + function saveSequence() { + const sequence = Array.from(slots).map(slot => slot.textContent || ""); + localStorage.setItem("emojiSequence", JSON.stringify(sequence)); + } +}); + diff --git a/static/emoji.js b/static/emoji.js new file mode 100644 index 0000000..b325106 --- /dev/null +++ b/static/emoji.js @@ -0,0 +1,45 @@ +// emoji.js – zentrale Emoji-Liste für Emoji Evolution + +export const ALL_EMOJIS = [ + // Faces + "😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", "😊", "😇", + "🙂", "🙃", "😉", "😌", "😍", "🥰", "😘", "😗", "😙", "😚", + "😋", "😛", "😝", "😜", "🤪", "🤨", "🧐", "🤓", "😎", "🥳", + "🤯", "😤", "😡", "😠", "🤬", "😳", "🥺", "😢", "😭", "😱", + "😰", "😥", "😓", "🤗", "🤔", "🤭", "🤫", "🤥", "😶", "😐", + "😑", "😬", "🙄", "😯", "😦", "😧", "😮", "😲", "🥱", "😴", + "😪", "😵", "🤢", "🤮", "🤧", "😷", "🤒", "🤕", "🤑", "😈", + "👿", "👹", "👺", "💀", "👻", "👽", "🤖", "🎃", "😺", "😸", + "😹", "😻", "😼", "😽", "🙀", "😿", "😾", + + // New Unicode Faces / People + "🫠", "🫣", "🫡", "🫥", "🫢", "🫨", "🫤", "🫦", "🫧", "🫰", + "🫶", "🫱", "🫲", "🫳", "🫴", "🫵", "🫂", "🫄", "🫃", "🫅", + + // Animals & Fauna + "🐶", "🐱", "🐭", "🐹", "🐰", "🦊", "🐻", "🐼", "🐨", "🐯", + "🦁", "🐮", "🐷", "🐸", "🐵", "🐔", "🐧", "🐦", "🐤", "🐣", + "🦆", "🦅", "🦉", "🦇", "🐺", "🐗", "🐴", "🦄", "🐝", "🐛", + "🦋", "🐌", "🐞", "🐜", "🦂", "🐢", "🐍", "🦎", "🦖", "🦕", + + // Funny / Objects / Faces / Weird + "💩", "🪿", "🍌", "🥒", "🥚", "🍕", "🍟", "🍿", "🎂", "🧁", + "🍭", "🍩", "🍦", "🎈", "🎉", "🎊", "🎭", "👯", "🕺", "💃", + + // Weird & Misc + "🧠", "🦷", "🦴", "🦻", "🧏", "🧌", "🪳", "🪰", "🪱", "🪲", + "🪨", "🧿", "🪬", "🧸", "🪦", "🪞", "🪡", "🪢", "🪤", + "🪥", "🪜", "🧃", "🧊", "🧪", "🧬", "🧫", "🧯", "🧱", "🪓", + + // Flora & Additional Fauna + "🦀", "🦞", "🦐", "🦑", "🐙", "🐚", "🐬", "🐳", "🐋", "🐊", + "🐆", "🐅", "🐃", "🐂", "🐄", "🦌", "🦬", "🐘", "🦣", "🦏", + "🦛", "🐪", "🐫", "🦙", "🦒", "🐓", "🦃", "🕊", "🦜", "🦢", + "🦩", "🦚", "🦤", "🪶", "🪺", "🦔", "🐇", "🐁", "🐀", "🐿", + "🦫", "🦦", "🦥", "🐾", + + // Flora + "🌵", "🎄", "🌲", "🌳", "🌴", "🌱", "🌿", "☘️", "🍀", + "🎍", "🪷", "💐", "🌸", "🌼", "🌻", "🌺", "🌹", "🥀", "🪻" +]; + diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..b6fe4c0 --- /dev/null +++ b/static/index.html @@ -0,0 +1,30 @@ + + + + + Emoji Evolution: The Single-Player Puzzle + + + +

Emoji Evolution: Your Ultimate Puzzle Experience

+ +

Puzzle Area

+
+
+
+
+
+ +

Emoji Bank

+
+ +

Solution Check

+
+ +
+
+ + + + + diff --git a/static/ollama.js b/static/ollama.js new file mode 100644 index 0000000..c61ba3c --- /dev/null +++ b/static/ollama.js @@ -0,0 +1,35 @@ +// ollama.js – OpenAI-kompatibler API-Aufruf für Open-WebUI + +export async function checkWithOllama(sequence) { + const prompt = sequence.join(" "); + + try { + const response = await fetch("https://at1.dynproxy.net/api/chat/completions", { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": "Bearer sk-d0e3a491b19c435a975b234969298cd0" + }, + body: JSON.stringify({ + model: "gemma3:1b", + messages: [ + { role: "system", content: "Du bist ein Emoji-Detektiv für Kinder. Bewerte jedes Emoji in genau einer Zeile im Format: Position X: ✅ oder ❌ Emoji – einfache, freundliche Begründung." }, + { role: "user", content: prompt } ], + stream: false + }) + }); + + if (!response.ok) { + console.error("Ollama API Error:", response.status); + return "(Fehler beim LLM-Request)"; + } + + const data = await response.json(); + return data.choices?.[0]?.message?.content?.trim() || "(keine Antwort vom Modell)"; + + } catch (error) { + console.error("LLM-Request fehlgeschlagen:", error); + return "(Verbindungsfehler mit Ollama)"; + } +} + diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..d623f41 --- /dev/null +++ b/static/style.css @@ -0,0 +1,93 @@ +/* Normal Stylesheet for Emoji Evolution */ + +body { + max-width: 960px; + margin: 0 auto; + padding: 0; + font-family: Arial, sans-serif; + text-align: center; + background-color: #ffffff; + color: #000000; + line-height: 1.4; +} + +#puzzle-area { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 15px; + margin: 20px 0; +} + +.emoji-slot { + width: 60px; + height: 60px; + border: 2px dashed #34495E; + background-color: #ECF0F1; + font-size: 32px; + line-height: 60px; +} + +#emoji-bank { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 15px; + margin: 20px 0; +} + +.emoji { + font-size: 32px; + cursor: move; + color: #4A90E2; +} + +.button-group { + display: flex; + justify-content: center; + gap: 10px; + margin: 20px 0; +} + +#submit-btn, +#reset-btn { + padding: 10px 20px; + background-color: #4A90E2; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + display: inline-block; + margin: 0; +} + +#submit-btn:hover, +#reset-btn:hover { + background-color: #F39C12; +} + +.secondary-button { + background-color: #bdc3c7; + color: #2c3e50; +} + +#feedback { + font-size: 18px; + margin-top: 20px; + color: #34495E; +} + +.page-break { + margin-bottom: 30px; +} + +img { + max-width: 100%; + height: auto; +} + +table { + border-collapse: collapse; + width: 100%; +} + 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..33d6c52 --- /dev/null +++ b/venv/bin/activate @@ -0,0 +1,69 @@ +# 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 + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + 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 + +VIRTUAL_ENV=/var/www/emojievolution/venv +export VIRTUAL_ENV + +_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 + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh new file mode 100644 index 0000000..725f2b6 --- /dev/null +++ b/venv/bin/activate.csh @@ -0,0 +1,26 @@ +# 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 /var/www/emojievolution/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..745af22 --- /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 /var/www/emojievolution/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..02f1dd3 --- /dev/null +++ b/venv/bin/fastapi @@ -0,0 +1,8 @@ +#!/var/www/emojievolution/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/pip b/venv/bin/pip new file mode 100755 index 0000000..a296cb4 --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,8 @@ +#!/var/www/emojievolution/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..a296cb4 --- /dev/null +++ b/venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/var/www/emojievolution/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.11 b/venv/bin/pip3.11 new file mode 100755 index 0000000..a296cb4 --- /dev/null +++ b/venv/bin/pip3.11 @@ -0,0 +1,8 @@ +#!/var/www/emojievolution/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.11 b/venv/bin/python3.11 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/venv/bin/python3.11 @@ -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..f1c5564 --- /dev/null +++ b/venv/bin/uvicorn @@ -0,0 +1,8 @@ +#!/var/www/emojievolution/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.11/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2010 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.11/site-packages/MarkupSafe-3.0.2.dist-info/METADATA b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/METADATA new file mode 100644 index 0000000..82261f2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/METADATA @@ -0,0 +1,92 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 3.0.2 +Summary: Safely add untrusted strings to HTML/XML markup. +Maintainer-email: Pallets +License: Copyright 2010 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. + +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source, https://github.com/pallets/markupsafe/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-File: LICENSE.txt + +# MarkupSafe + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +## Examples + +```pycon +>>> from markupsafe import Markup, escape + +>>> # escape replaces special characters and wraps in Markup +>>> escape("") +Markup('<script>alert(document.cookie);</script>') + +>>> # wrap in Markup to mark text "safe" and prevent escaping +>>> Markup("Hello") +Markup('hello') + +>>> escape(Markup("Hello")) +Markup('hello') + +>>> # Markup is a str subclass +>>> # methods and operators escape their arguments +>>> template = Markup("Hello {name}") +>>> template.format(name='"World"') +Markup('Hello "World"') +``` + +## Donate + +The Pallets organization develops and supports MarkupSafe 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 diff --git a/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/RECORD b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/RECORD new file mode 100644 index 0000000..b474513 --- /dev/null +++ b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-3.0.2.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-3.0.2.dist-info/METADATA,sha256=aAwbZhSmXdfFuMM-rEHpeiHRkBOGESyVLJIuwzHP-nw,3975 +MarkupSafe-3.0.2.dist-info/RECORD,, +MarkupSafe-3.0.2.dist-info/WHEEL,sha256=OhaudQk1f3YCu0uQO5v6u-i01XPoX70c0R3T_XY-jOo,151 +MarkupSafe-3.0.2.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=sr-U6_27DfaSrj5jnHYxWN-pvhM27sjlDplMDPZKm7k,13214 +markupsafe/__pycache__/__init__.cpython-311.pyc,, +markupsafe/__pycache__/_native.cpython-311.pyc,, +markupsafe/_native.py,sha256=hSLs8Jmz5aqayuengJJ3kdT5PwNpBWpKrmQSdipndC8,210 +markupsafe/_speedups.c,sha256=O7XulmTo-epI6n2FtMVOrJXl8EAaIwD2iNYmBI5SEoQ,4149 +markupsafe/_speedups.cpython-311-x86_64-linux-gnu.so,sha256=6IDH6Z1ajjClhfGerTB8WLb81uXUpLD8e-e1WzCirVY,43456 +markupsafe/_speedups.pyi,sha256=ENd1bYe7gbBUf2ywyYWOGUpnXOHNJ-cgTNqetlW8h5k,41 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL new file mode 100644 index 0000000..35db8b0 --- /dev/null +++ b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.2.0) +Root-Is-Purelib: false +Tag: cp311-cp311-manylinux_2_17_x86_64 +Tag: cp311-cp311-manylinux2014_x86_64 + diff --git a/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/venv/lib/python3.11/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/venv/lib/python3.11/site-packages/__pycache__/typing_extensions.cpython-311.pyc b/venv/lib/python3.11/site-packages/__pycache__/typing_extensions.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30121461ce201500349bbfbc2b010ff4c26446d3 GIT binary patch literal 189002 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 aMEUFq8T^%BeQ!ki)rj`qUgcL)GWb8m;IsSy literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/_distutils_hack/__init__.py b/venv/lib/python3.11/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..f987a53 --- /dev/null +++ b/venv/lib/python3.11/site-packages/_distutils_hack/__init__.py @@ -0,0 +1,222 @@ +# don't import any costly modules +import sys +import os + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +def warn_distutils_present(): + if 'distutils' not in sys.modules: + return + if is_pypy and sys.version_info < (3, 7): + # PyPy for 3.6 unconditionally imports distutils, so bypass the warning + # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250 + return + import warnings + + warnings.warn( + "Distutils was imported before Setuptools, but importing Setuptools " + "also replaces the `distutils` module in `sys.modules`. This may lead " + "to undesirable behaviors or errors. To avoid these issues, avoid " + "using distutils directly, ensure that setuptools is installed in the " + "traditional way (e.g. not an editable install), and/or make sure " + "that setuptools is always imported before distutils." + ) + + +def clear_distutils(): + if 'distutils' not in sys.modules: + return + import warnings + + warnings.warn("Setuptools is replacing distutils.") + mods = [ + name + for name in sys.modules + if name == "distutils" or name.startswith("distutils.") + ] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local') + return which == 'local' + + +def ensure_local_distutils(): + import importlib + + clear_distutils() + + # With the DistutilsMetaFinder in place, + # perform an import to cause distutils to be + # loaded from setuptools._distutils. Ref #2906. + with shim(): + importlib.import_module('distutils') + + # check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + assert 'setuptools._distutils.log' not in sys.modules + + +def do_override(): + """ + Ensure that the local copy of distutils is preferred over stdlib. + + See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 + for more motivation. + """ + if enabled(): + warn_distutils_present() + ensure_local_distutils() + + +class _TrivialRe: + def __init__(self, *patterns): + self._patterns = patterns + + def match(self, string): + return all(pat in string for pat in self._patterns) + + +class DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + # optimization: only consider top level modules and those + # found in the CPython test suite. + if path is not None and not fullname.startswith('test.'): + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + if self.is_cpython(): + return + + import importlib + import importlib.abc + import importlib.util + + try: + mod = importlib.import_module('setuptools._distutils') + except Exception: + # There are a couple of cases where setuptools._distutils + # may not be present: + # - An older Setuptools without a local distutils is + # taking precedence. Ref #2957. + # - Path manipulation during sitecustomize removes + # setuptools from the path but only after the hook + # has been loaded. Ref #2980. + # In either case, fall back to stdlib behavior. + return + + class DistutilsLoader(importlib.abc.Loader): + def create_module(self, spec): + mod.__name__ = 'distutils' + return mod + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader( + 'distutils', DistutilsLoader(), origin=mod.__file__ + ) + + @staticmethod + def is_cpython(): + """ + Suppress supplying distutils for CPython (build and tests). + Ref #2965 and #3007. + """ + return os.path.isfile('pybuilddir.txt') + + def spec_for_pip(self): + """ + Ensure stdlib distutils when running under pip. + See pypa/pip#8761 for rationale. + """ + if self.pip_imported_during_build(): + return + clear_distutils() + self.spec_for_distutils = lambda: None + + @classmethod + def pip_imported_during_build(cls): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + + return any( + cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None) + ) + + @staticmethod + def frame_file_is_setup(frame): + """ + Return True if the indicated frame suggests a setup.py file. + """ + # some frames may not have __file__ (#2940) + return frame.f_globals.get('__file__', '').endswith('setup.py') + + def spec_for_sensitive_tests(self): + """ + Ensure stdlib distutils when running select tests under CPython. + + python/cpython#91169 + """ + clear_distutils() + self.spec_for_distutils = lambda: None + + sensitive_tests = ( + [ + 'test.test_distutils', + 'test.test_peg_generator', + 'test.test_importlib', + ] + if sys.version_info < (3, 10) + else [ + 'test.test_distutils', + ] + ) + + +for name in DistutilsMetaFinder.sensitive_tests: + setattr( + DistutilsMetaFinder, + f'spec_for_{name}', + DistutilsMetaFinder.spec_for_sensitive_tests, + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + DISTUTILS_FINDER in sys.meta_path or insert_shim() + + +class shim: + def __enter__(self): + insert_shim() + + def __exit__(self, exc, value, tb): + remove_shim() + + +def insert_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass diff --git a/venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eeda7441b860835d2ae269b7772663b2e5254eb1 GIT binary patch literal 11159 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/override.cpython-311.pyc b/venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/override.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e932af1a24d94f428c509720787cba1fa395990 GIT binary patch literal 316 zcmZ3^%ge<81kul4r|SUe#~=<2Fhd!i9e|AK3``8E3@HrD7#SE=12F_FfU{sCAbJ@P zuZ9aSGNdpDGiWm1;*U?sEG{W6$;>H^&qz$p_5+G>#m8sn7UUO|#K+&_PRWnYFH0>d z%1lXJ$?zFuz^_pKvcw|&^73;1)ZF~6%+#{{9H0UDdHQ9kd1d-JnMwKul_eSZdB%E% zhWf>sC8@dvK$8>GQ;YS{Y}1DstyfU_i^C>2KczG$)vkyGXbZ>_#Tr2312ZEd;|&I` j2CfU-G8Y+SuQ147XVARFpm~u&`wD~h1sEz~11bgpjLT9| literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/_distutils_hack/override.py b/venv/lib/python3.11/site-packages/_distutils_hack/override.py new file mode 100644 index 0000000..2cc433a --- /dev/null +++ b/venv/lib/python3.11/site-packages/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/METADATA b/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/METADATA new file mode 100644 index 0000000..3ac05cf --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/annotated_types-0.7.0.dist-info/RECORD b/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/RECORD new file mode 100644 index 0000000..cb983b0 --- /dev/null +++ b/venv/lib/python3.11/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-311.pyc,, +annotated_types/__pycache__/test_cases.cpython-311.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.11/site-packages/annotated_types-0.7.0.dist-info/WHEEL b/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/WHEEL new file mode 100644 index 0000000..516596c --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE b/venv/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE new file mode 100644 index 0000000..d99323a --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/annotated_types/__init__.py b/venv/lib/python3.11/site-packages/annotated_types/__init__.py new file mode 100644 index 0000000..74e0dee --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/annotated_types/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/annotated_types/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50a8585632ce9727a04605b3a3868f748228cb08 GIT binary patch literal 20561 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 jQR5&mgs;7XtH)4l^&TfK!A5%9kO;|}5J literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/annotated_types/__pycache__/test_cases.cpython-311.pyc b/venv/lib/python3.11/site-packages/annotated_types/__pycache__/test_cases.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd997f0d234c603c8dab68a5802ac7f357d9dafa GIT binary patch literal 15452 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/annotated_types/py.typed b/venv/lib/python3.11/site-packages/annotated_types/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/annotated_types/test_cases.py b/venv/lib/python3.11/site-packages/annotated_types/test_cases.py new file mode 100644 index 0000000..d9164d6 --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio-4.9.0.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/LICENSE b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/LICENSE new file mode 100644 index 0000000..104eebf --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/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.11/site-packages/anyio-4.9.0.dist-info/METADATA b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/METADATA new file mode 100644 index 0000000..9d87e1d --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/METADATA @@ -0,0 +1,105 @@ +Metadata-Version: 2.2 +Name: anyio +Version: 4.9.0 +Summary: High level compatibility layer for multiple asynchronous event loop implementations +Author-email: Alex Grönholm +License: 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: License :: OSI Approved :: MIT License +Classifier: Framework :: AnyIO +Classifier: Typing :: Typed +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +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 +Requires-Python: >=3.9 +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: sniffio>=1.1 +Requires-Dist: typing_extensions>=4.5; python_version < "3.13" +Provides-Extra: trio +Requires-Dist: trio>=0.26.1; extra == "trio" +Provides-Extra: test +Requires-Dist: anyio[trio]; extra == "test" +Requires-Dist: blockbuster>=1.5.23; extra == "test" +Requires-Dist: coverage[toml]>=7; extra == "test" +Requires-Dist: exceptiongroup>=1.2.0; extra == "test" +Requires-Dist: hypothesis>=4.0; extra == "test" +Requires-Dist: psutil>=5.9; extra == "test" +Requires-Dist: pytest>=7.0; extra == "test" +Requires-Dist: trustme; extra == "test" +Requires-Dist: truststore>=0.9.1; python_version >= "3.10" and extra == "test" +Requires-Dist: uvloop>=0.21; (platform_python_implementation == "CPython" and platform_system != "Windows" and python_version < "3.14") and extra == "test" +Provides-Extra: doc +Requires-Dist: packaging; extra == "doc" +Requires-Dist: Sphinx~=8.2; extra == "doc" +Requires-Dist: sphinx_rtd_theme; extra == "doc" +Requires-Dist: sphinx-autodoc-typehints>=1.2.0; extra == "doc" + +.. 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 + +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. + +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 +* Asynchronous file I/O (using worker threads) +* Signal handling + +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/ +.. _Hypothesis: https://hypothesis.works/ diff --git a/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/RECORD b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/RECORD new file mode 100644 index 0000000..1e5fa9f --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/RECORD @@ -0,0 +1,88 @@ +anyio-4.9.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +anyio-4.9.0.dist-info/LICENSE,sha256=U2GsncWPLvX9LpsJxoKXwX8ElQkJu8gCO9uC6s8iwrA,1081 +anyio-4.9.0.dist-info/METADATA,sha256=vvkWPXXTbrpTCFK7zdcYwQcSQhx6Q4qITM9t_PEQCrY,4682 +anyio-4.9.0.dist-info/RECORD,, +anyio-4.9.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91 +anyio-4.9.0.dist-info/entry_points.txt,sha256=_d6Yu6uiaZmNe0CydowirE9Cmg7zUL2g08tQpoS3Qvc,39 +anyio-4.9.0.dist-info/top_level.txt,sha256=QglSMiWX8_5dpoVAEIHdEYzvqFMdSYWmCj6tYw2ITkQ,6 +anyio/__init__.py,sha256=t8bZuNXa5ncwXBaNKbv48BDgZt48RT_zCEtrnPmjNU8,4993 +anyio/__pycache__/__init__.cpython-311.pyc,, +anyio/__pycache__/from_thread.cpython-311.pyc,, +anyio/__pycache__/lowlevel.cpython-311.pyc,, +anyio/__pycache__/pytest_plugin.cpython-311.pyc,, +anyio/__pycache__/to_interpreter.cpython-311.pyc,, +anyio/__pycache__/to_process.cpython-311.pyc,, +anyio/__pycache__/to_thread.cpython-311.pyc,, +anyio/_backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/_backends/__pycache__/__init__.cpython-311.pyc,, +anyio/_backends/__pycache__/_asyncio.cpython-311.pyc,, +anyio/_backends/__pycache__/_trio.cpython-311.pyc,, +anyio/_backends/_asyncio.py,sha256=AT1oaTfCE-9YFxooMlvld2yDqY5U2A-ANMcBDh9eRfI,93455 +anyio/_backends/_trio.py,sha256=HVfDqRGQ7Xj3JfTcYdgzmC7pZEplqU4NOO5kxNNSZnk,40429 +anyio/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/_core/__pycache__/__init__.cpython-311.pyc,, +anyio/_core/__pycache__/_asyncio_selector_thread.cpython-311.pyc,, +anyio/_core/__pycache__/_eventloop.cpython-311.pyc,, +anyio/_core/__pycache__/_exceptions.cpython-311.pyc,, +anyio/_core/__pycache__/_fileio.cpython-311.pyc,, +anyio/_core/__pycache__/_resources.cpython-311.pyc,, +anyio/_core/__pycache__/_signals.cpython-311.pyc,, +anyio/_core/__pycache__/_sockets.cpython-311.pyc,, +anyio/_core/__pycache__/_streams.cpython-311.pyc,, +anyio/_core/__pycache__/_subprocesses.cpython-311.pyc,, +anyio/_core/__pycache__/_synchronization.cpython-311.pyc,, +anyio/_core/__pycache__/_tasks.cpython-311.pyc,, +anyio/_core/__pycache__/_tempfile.cpython-311.pyc,, +anyio/_core/__pycache__/_testing.cpython-311.pyc,, +anyio/_core/__pycache__/_typedattr.cpython-311.pyc,, +anyio/_core/_asyncio_selector_thread.py,sha256=2PdxFM3cs02Kp6BSppbvmRT7q7asreTW5FgBxEsflBo,5626 +anyio/_core/_eventloop.py,sha256=t_tAwBFPjF8jrZGjlJ6bbYy6KA3bjsbZxV9mvh9t1i0,4695 +anyio/_core/_exceptions.py,sha256=RlPRlwastdmfDPoskdXNO6SI8_l3fclA2wtW6cokU9I,3503 +anyio/_core/_fileio.py,sha256=qFZhkLIz0cGXluvih_vcPUTucgq8UFVgsTCtYbijZIg,23340 +anyio/_core/_resources.py,sha256=NbmU5O5UX3xEyACnkmYX28Fmwdl-f-ny0tHym26e0w0,435 +anyio/_core/_signals.py,sha256=vulT1M1xdLYtAR-eY5TamIgaf1WTlOwOrMGwswlTTr8,905 +anyio/_core/_sockets.py,sha256=5Okc_UThGDEN9KCnsIhqWPRHBNuSy6b4NmG1i51TVF4,27150 +anyio/_core/_streams.py,sha256=OnaKgoDD-FcMSwLvkoAUGP51sG2ZdRvMpxt9q2w1gYA,1804 +anyio/_core/_subprocesses.py,sha256=EXm5igL7dj55iYkPlbYVAqtbqxJxjU-6OndSTIx9SRg,8047 +anyio/_core/_synchronization.py,sha256=DwUh8Tl6cG_UMVC_GyzPoC_U9BpfDfjMl9SINSxcZN4,20320 +anyio/_core/_tasks.py,sha256=f3CuWwo06cCZ6jaOv-JHFKWkgpgf2cvaF25Oh4augMA,4757 +anyio/_core/_tempfile.py,sha256=s-_ucacXbxBH5Bo5eo65lN0lPwZQd5B8yNN_9nARpCM,19696 +anyio/_core/_testing.py,sha256=YUGwA5cgFFbUTv4WFd7cv_BSVr4ryTtPp8owQA3JdWE,2118 +anyio/_core/_typedattr.py,sha256=P4ozZikn3-DbpoYcvyghS_FOYAgbmUxeoU8-L_07pZM,2508 +anyio/abc/__init__.py,sha256=c2OQbTCS_fQowviMXanLPh8m29ccwkXmpDr7uyNZYOo,2652 +anyio/abc/__pycache__/__init__.cpython-311.pyc,, +anyio/abc/__pycache__/_eventloop.cpython-311.pyc,, +anyio/abc/__pycache__/_resources.cpython-311.pyc,, +anyio/abc/__pycache__/_sockets.cpython-311.pyc,, +anyio/abc/__pycache__/_streams.cpython-311.pyc,, +anyio/abc/__pycache__/_subprocesses.cpython-311.pyc,, +anyio/abc/__pycache__/_tasks.cpython-311.pyc,, +anyio/abc/__pycache__/_testing.cpython-311.pyc,, +anyio/abc/_eventloop.py,sha256=UmL8DZCvQTgxzmyBZcGm9kWj9VQY8BMWueLh5S8yWN4,9682 +anyio/abc/_resources.py,sha256=DrYvkNN1hH6Uvv5_5uKySvDsnknGVDe8FCKfko0VtN8,783 +anyio/abc/_sockets.py,sha256=KhWtJxan8jpBXKwPaFeQzI4iRXdFaOIn0HXtDZnaO7U,6262 +anyio/abc/_streams.py,sha256=He_JpkAW2g5veOzcUq0XsRC2nId_i35L-d8cs7Uj1ZQ,6598 +anyio/abc/_subprocesses.py,sha256=cumAPJTktOQtw63IqG0lDpyZqu_l1EElvQHMiwJgL08,2067 +anyio/abc/_tasks.py,sha256=yJWbMwowvqjlAX4oJ3l9Is1w-zwynr2lX1Z02AWJqsY,3080 +anyio/abc/_testing.py,sha256=tBJUzkSfOXJw23fe8qSJ03kJlShOYjjaEyFB6k6MYT8,1821 +anyio/from_thread.py,sha256=MbXHZpgM9wgsRkbGhMNMomEGYj7Y_QYq6a5BZ3c5Ev8,17478 +anyio/lowlevel.py,sha256=nkgmW--SdxGVp0cmLUYazjkigveRm5HY7-gW8Bpp9oY,4169 +anyio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/pytest_plugin.py,sha256=qXNwk9Pa7hPQKWocgLl9qijqKGMkGzdH2wJa-jPkGUM,9375 +anyio/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +anyio/streams/__pycache__/__init__.cpython-311.pyc,, +anyio/streams/__pycache__/buffered.cpython-311.pyc,, +anyio/streams/__pycache__/file.cpython-311.pyc,, +anyio/streams/__pycache__/memory.cpython-311.pyc,, +anyio/streams/__pycache__/stapled.cpython-311.pyc,, +anyio/streams/__pycache__/text.cpython-311.pyc,, +anyio/streams/__pycache__/tls.cpython-311.pyc,, +anyio/streams/buffered.py,sha256=UCldKC168YuLvT7n3HtNPnQ2iWAMSTYQWbZvzLwMwkM,4500 +anyio/streams/file.py,sha256=6uoTNb5KbMoj-6gS3_xrrL8uZN8Q4iIvOS1WtGyFfKw,4383 +anyio/streams/memory.py,sha256=o1OVVx0OooteTTe2GytJreum93Ucuw5s4cAsr3X0-Ag,10560 +anyio/streams/stapled.py,sha256=U09pCrmOw9kkNhe6tKopsm1QIMT1lFTFvtb-A7SIe4k,4302 +anyio/streams/text.py,sha256=6x8w8xlfCZKTUWQoJiMPoMhSSJFUBRKgoBNSBtbd9yg,5094 +anyio/streams/tls.py,sha256=HxzpVmUgo8SUSIBass_lvef1pAI1uRSrnysM3iEGzl4,13199 +anyio/to_interpreter.py,sha256=UhuNCIucCRN7ZtyJg35Mlamzs1JpgDvK4xnL4TDWrAo,6527 +anyio/to_process.py,sha256=ZvruelRM-HNmqDaql4sdNODg2QD_uSlwSCxnV4OhsfQ,9595 +anyio/to_thread.py,sha256=WM2JQ2MbVsd5D5CM08bQiTwzZIvpsGjfH1Fy247KoDQ,2396 diff --git a/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/WHEEL b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/WHEEL new file mode 100644 index 0000000..9c3ae63 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (76.0.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/entry_points.txt b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/entry_points.txt new file mode 100644 index 0000000..44dd9bd --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[pytest11] +anyio = anyio.pytest_plugin diff --git a/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/top_level.txt b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/top_level.txt new file mode 100644 index 0000000..c77c069 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio-4.9.0.dist-info/top_level.txt @@ -0,0 +1 @@ +anyio diff --git a/venv/lib/python3.11/site-packages/anyio/__init__.py b/venv/lib/python3.11/site-packages/anyio/__init__.py new file mode 100644 index 0000000..578cda6 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/__init__.py @@ -0,0 +1,85 @@ +from __future__ import annotations + +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_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 BrokenWorkerIntepreter as BrokenWorkerIntepreter +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 DelimiterNotFound as DelimiterNotFound +from ._core._exceptions import EndOfStream as EndOfStream +from ._core._exceptions import IncompleteRead as IncompleteRead +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 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 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 diff --git a/venv/lib/python3.11/site-packages/anyio/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4ca447f8d39507b43dd1e8df8a692a6908e1097 GIT binary patch literal 4748 zcma);$xj?f7KfwQimh17*ck6Nt1)G4Y-7M+b}$&+6t;V!r#qEo1~{8sN|9M$`sBI! zFo&MjNIgeOBY8BMOaCe97Sg2Z)Y3>JwdP`}FQY!qd#@_7gQ7JqJ%07Yi#_7SqyCmk z)id~f_3!`e{Gpw(e_?gbv?gT#II z4QGfC5%=2}=O({NJODh*hl#J-x18JjHt`_v2p=K70epwwAszz0%kL6rfba2p#5aLQ z`6%%)@O^%t_!jUOA0xgEJkH07M}Q~z1o0i<2mAr?U3=1*;#0);fFJUQ#G}B|e46+^ z@C=_J9s{1`v&7@Tb9|0?!k%{)_yX|*;6=VjJPEwSmx!l;m-#aBL*PgJ5%Dze3SS|f z0bb>+#IwMU`D5Zad(Bzr>%{ZGPxuq!1>n#4XT*!Z8+?O!$<8{Pe3N(?_$hx%{0R6N zf0kesOgx9b&)>om{73vA*_+=T;YXmhd7FS9@K^lIu`l~MhmpPz+*~nN-&R5`{1rcM zejn4v-{xa=44D*P3a)(>xB2717u;OSvi|j-(bb`_wv#Z^HO@)s-x(B?#W#tm)$_*qzI^gsY9{miS!IX z^R~|9{e$D9w9nd}FU;fa);VEYjs@ebdBK90cTHT^ylbv+X9Fp82Z~M0uHiX38)n@Q zIyUIsJje-iItZk-l@G+K=k4Zm@p|i@dwJWOu{~oKn$}JG2d=ST*?53ePxRmgI=!55 zwe6y_ZeQxTxX`K_xK2DILu}`5`v97!skv|MxVo)LVF;^qeun3|!hriR@O&HNV&1i0 zLb=O;4Fp0fx#4#5W=`{AT_S+$?(%BrrW{{1fGE;UQ(Eq}2TQ}Et2?4pOzrDd02|j$eT&X9O^)JDe$&4%t)SGt zIKW4ac$toHJb9pbTVLZb`tgl7(t+oWBB}u*S^H3Ip4D@@VFd@P#n6EjcOG+P@hSO% zW#B`ooAq4N!lwm=_M?K*rh0x4UK-Rl6DW06tHoGq!f&M}702^pUY8h|by?x)xfk%n zaH^w%(y4uOI=iA}H>WqBX0_$Twe^kpIcVK5ORqR@}aZ^t&`5KiIqi!$R(`Zge@%>BaKp8yeZr& zG;M`JG`Mlsa(6WJ;T?8R$YJs$kG6&HTi}s*sL25G(4J)$Ux-?hrDxY1VD8ZLIC&K6 zHO=wNye%}Xz`m)`-2=-TTI<)aVmlw?B~(bv_k|XC%2EtzkUrhO_Pm^|2DilDcruAn zi&BSzzX)XmNTD_E^wJPHO7F4}D^n;D6J@MDDXRy$u!C-kV2|72&OE{lO0%b z8s!X1CpL)}CrjzumuJ!4RO(sGUcT&7oRo`vc@9T8k8%O!BFZI{%P3b+uA*E+=|<^6 z=|$;7=?D2R6+L5L4xqC=osC-!u|XAP-$D&Uv2Oc?nmygl z3%`)mG@?Qh-T-zh)cb)h1ApHNUKDCI4YM+Y<6{`&@9Y;)_UlS!PnVhf{rwCi)2}VD z=h=CTvkXM(UdFbzGP#4`h3DQL8XnI0@UQj;B+p%aNB9|v^^B%jF64J@D0lE{?L_e{ zOv)V?8-IuRe}y1_UztcGB6cNI?I$)Csur=CP_>9X2~~?&U#MEd21C^%HW8{8vC&Yq zh%JYzMQlA(?W8vIAye$r+T0JBViB7PRg2iuP_>BN3ssBQaHv|udPCJtYE#~8E@X;D zY$;SNVs}H;PCCP9Aye#qMMa|GJ^L-GVTr{=$QC}flP+Bu6Q=mI<&`hEJiyAgS?($C zRlc4FAyX`3#?2G8!(o?7`m+zFXtCq1l8$P|mzBGjIAs^vQ^ zPhhJdQ|!}D_4vr|YgkMAb@1)Nw+nw-`t#EF>))-vOLrfpyWchU95(mhlPk)r#VFbI zYX9~AUmD+Ry-W5VCj0-H9QiRh^26uvl9PwY$@eT#-4mVfew{q5J^SCEsv2G`zFL$5 HlJ)-pCXl;~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/__pycache__/from_thread.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/__pycache__/from_thread.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..637f95ddca80cc6675625aea8c49d45f68b46fec GIT binary patch literal 26166 zcmdUXd2k%pnP2zZgBf4|%mBniV2Fzx5(jUJAa#HgFCCC=QnCy!7aUGE$sy;Uy9a~_ zfi_Gt7RZuq$}27DU1o!I94!@TQ(PyTIGar(N^9>XTbr6erh>^-m{L`aT4(r?( z+Dhg3z1Q8-Ju`qPc~i+Y8sEHr_wl{&eee6e_kORwzD~gN>;L_)P9J<)5dI5&=#Ps# z#QQsKf^b8S1W8N?NpVsX$!$y6CT;k&C+tbbq$BB^bS7PsE*9oUxRahq4|6*c-elcm zUD7w{OZq4M%+HmmPc}?8Bmf@VwOvmx$i8_g0cdFUNG z!tk$!?P6gA2pg=Z#ba^<3tNw{4c4%CkoY}43t@7%?Dq=Nc4>z+dc|20HYV+qwxG6q zB->FTvg;R=Dk2tr(Nrp(iDu&IlsXZy7ro;%(Re0$G9ec|`=f~jb9oQRDOrhT(h5?z z4o+vL6&Z0m$4{ymB^t|&s~1zT{pnOjel_!aG!;E9E5%klu)@C~#^WVGt8ptQ3v2({R zo|hxeqJ2DdvFK(sj>n2_@_i|)6dkdsnkjnH7i1-oj!M6v@kjEyDft32N~F{0QBD)( z9HrJwQI2v-Dy|`~STq%r6A4+Gl3$HY@w)mmtTu^sESgY}lk)&&g!cIMv)D&t>GN{2 zDTXR%e-5Zt@_8N&tpVf zFQ(2TQPFd3>ML^QLNrly9Gi-zk0A?hEPWxW#G@&+@k?oSTsf^CD>_b1r(zGc=;Qdx zD?I%xdW7T0hr-5qzoKV){CLq3Mf!)0mC=hXMaI~tV#ee_Eot((1wp+3BRFmdULk{D z{W)vIykxWZ8G}l)Bq!t5^AJGbtW!|3UAD~#uiC#R%!qTgMK=A* zvAJtbm=ovh@7t}@45;sz&DMqSP_Kle;aD1jl8L9}Fm)EqgYYROokYk?S~({xVLr?w zbu7`?`KS_2vZ!M<6PsgECys^Br`0%R8%1f#>FFepL=B%xQ^s-_xWlFxPsV$9jD>J_ z7=t`5htsEc?5eu*T0Pu->`WY)>J0$8hSRCU#qdcvtW4_-N`)~qj=W%P*TlQP+)Ns% z9&st1=(=J{Y+6xJ$%=VUuY0q|#fI@rMv0%C&d3K8C9M?wUztv2;z{kR1*K}~sWYc| zAHM5QA}B%GM8(uwrkSz@ekxH)8k&a_qd?}-nVFeUIhj5imoKCf7^8G*6jSWNXd-@c z^!&xlnRIH~$d)am=w5l4<^|}EIvPz~jHgFUrH-7xShS-)${2FrK*huX=7mzL%Ne@Y z)}L=1Td2R+*p+YGxZqrHKDg&=F9~*Ms0{8kbQJuDKC#;Zb)O0V9|wXZr_CEG*%9r* zg9oKL!QZ~@8(H#=+|JxN_CZV5HE|K?|zUI=T2GK%q=P&NZ+4jO$vcu(IE+b;dHhdYYsw5m0-W4Z^i_++A zELn6<@j{4kQsu-cW*$zxxOg6ynPt`b>jVMa#ZTP5Was;aNfC41>`eL9lYI=BCaGXAP!d(cE2B zEPJeJzm46{Yxb9f8}{!wE};w08hrQ)3_}Hzf&IfU7!$vqJ7Y}3m(cyDoWS^0KXW!K zyCMpgQI|`$Z`fu;oo(?7$j4~+A}tbC&&ur)1skO|`s1v@EWwxU94WK!36?&v&)JU( zeP1wT%q9vk+t+|@ob6JcMF9~Xn{vw2a4XLNfSsO-@>x5j>|-7(*k?snrxTfCy=9ga z>nRBQG@pw_2l4wrV`M;6dP+G!B{-A`%Erm~prReoi3z3bD(I@e%yPt%vyoL1+8p&H zvRARa6#f!_Kx~`ayX9U_{|{$w%`7~f_jeUKx^ImvcWhhg*p}vi>av ze-rqL2gF@8)34v>?LgkaHTmY=<>vKE&Fgc`k$iI`>#y-5V%PSY+iyLQ@7#9hSboRh zZ0C_|OXa(8un=rtc>Y1j{yAbVJa7I}`_N}swvIOmcbn?Q_t@`tc8>3~-`(jX_me&Q z#)J>YdiHnPl|jU_On;iT_}BLe8Dj$cY7^f)C9P8r1jN`KSSFkcHK}^66Yi+Mk=(7& zENAGfJP%hfpk|^RXLjngPCuv(iHvxBQ*rV;NV605`= z%nSF{_WkhXTQ4s-@}7=DSNPU*%UzExbv^deP=5C_xvppPUC&Zbdm#|a2i7eIHY^1; zfsI+uM&(P$qPS|AC=x3fEshU6R$d~D>sPBc&x6g;hat->*H+EXN={+~wuyfj zs4tzOwX;zBNB}@&}Z>;p$ri( zjx7*8Bod577VV&TWjxVnn-Zm{F#<9`1zGb@*FMr3&7*yTvLJd4Qsx(WBDXi)c`e($ zk1(XO;PJoVU-q;wdD?IG=Q}p$J4SMz(Y$9g>ltO(6J8FiUka?x1tR%CBD-j)8)sHOt>$g;yx`kDlcK09#0$~Dw7De4< z{++90^U4jgDI}v(2xat^Q60=JE4mr+m!;WtE4NOI@?A>X4S>e+sn@gQ=~;BECCA?Y8NcBo7u7fVZW7y=Op>e%k_jFL{J zrxBTC$V@mg!Uo;KJsHz;AM59pxu@EgZ*99inQcltax1oKa_W=X_FUgWibZ=Yp_+La zH)yszgH2;7wF9gdY1#cmjb(Ufj#-ao~&mN$0Ne$+U@%t zgxnBTZl8Hum@yXU8ayOX2lkky$<}@_bBGzDMA}mo%h>9b>4isWMC@V<*C9-iOiL4W zLOr2NBh(Ch*|;i13m~5;>jD(&r(&pwi4o|2TcE%d(dZOVx;cn-&CG_W5@G zvni~#=geDBVyMb^_bue993@cMRPvl{uWG8kv;4aVR!IoQw`_%m=6plSUcuf?yPd*fWz(_Z}+TH5n11IsO=OD&^!JU?Ck!OmREGx?Th zvVp4C^Gr3G(KN-sc%M4ex`@vQG8C#km5QLtB-hacg_TLcIo8FBHLnUO&1FbELCWnD zvmH#E!ewY-=vAN~C8C{z)N*zg3rot-K1k5s5MxSO7UJ<`O_EJ|oiZKQ$bQ7Gd=nLA z!eT}>Dv`d}Fcmu^$IeaZC9SO-9ZT>(L}n`S;ovQNfxK@3GTwX5-PxW!x#qq3=Dk_} zUhe<Hfxzlvp-yAC{wvLXQ5V8N zg)gFmZL@tx6S90hObVk!c#QgT>;&QP3F>U#lOqsmD)T5``6_`50#OXAl*1IuVTzKT z2Se6d(P1^>`~;b)B)R8^{jo+l`j#5{at#CdhJmbS#h3NZ!D1r@9lBu1w31QK-qh)$ zgM^(Hrqt-T@1ZD8BqXa4_cQmWR^kD|DJo&$x-l2Zd)C_0%*yoC^}PF|BcdQM)dmE? z;iK`>oHvo7s3ggBIFk;mXQne@DLs?Yw4M}^<9$>)rvjsm$WfXd;8#*m`G=!1Cd*5m z4ucV31F3?+k-!1PN#zMepi!(o>ea(|!c?ZFZLRF_vG9o#$CPRL#0jb_4-I1ivWgkw z5~gKV9YWlLP|zc?Q8+aR3BjFF3TSgNj_MgqV`yceFl8!k3@q2JQsfC}e%S1t$9O7n z0z__$eywIIQ}w&}m%ejg+&^K0z9(9Mdp1~!q(I((iU2dYZ50MLvgI4Q1}xmmo~|WN zSI*O&_jG4H-31@^qM~;j6Crlx{gGw=<|Y5;oPTTHzcs7BB|D<9cnoiu;`QO)Rke>b zECC?BF?5nlZToNy*QHci1{^QC&do5Rfd(la%e(@+5SSLEE*@vQnum>=?#9S0X5!ie z7uwJ0%#YAruM4kxwJGCT@Gc0aY}h&YFFCy=xW<|o7v}6g7QZK6a+&$VIhR#*qa@AC zhIKOR5UzRW9E&tGRgX2M(sI?iXiPbCWNSRA3R;k(!yH3*&pE9%!&G*e*YQhk3CaOU zup0ItM_-??1UgyFBc8z@>p9SGWj}pQNWGXLrdfMX%8^T+&(RvMp3?j~=c#N>rllM{=gG8| zzpVYNikH!^P|kS1;URM|`YkJIBwz|L1$~Hd&8w?!BJPQzcuM(AAq^KJvdjz^6F68G1MIWpG$L`upQFP zn>dxD@lnnYcoP7e%T4?gos7zH(KgMA@cg`{Mx-U1%%x^GRS-AqYZ3{Fic+zWz1&Xf zi4i^WUmy$hB)|i3FoDMJzjp1ltC!xm1d&?(hQ&~R-JU{Y=w4&{o4&VvC8zyq5zLCc zR|6iQspW?E2i}_lw}x_!>+_B4v-(@|B0bBb9G_7@u*KAjieZcR725MDYYEV3u_hOr zqLMTvLDs}tKy70}A>}e+6uX#8i}Qn1X=Ms5VEoiYZ4ajq+pN4q@#^AgJOxn@*oC6^ zfUf6?)NzqngyL-?KpSQ*{JBNRf>?mC8KImF6F6pgMLU#9iu>CDY8}7{TAb*4ijPEH zxx=fsPsUjMoRa@N}%jl%SEcR z8nGUf8ikJG>#kCp5b9VC_ALeba>0RoZ~*IO{l-FL>vH3|rN(uOgSo~?zA=(*j3A$O zp)r&Xpu23|tz}T~H-G>6YtLVO;f)s-Uckq)e{{(|YUuT#+QWM<(1mJvTgw2dxZ36R zFE#cr9yQASrAr8P-;Di(-MQd!J~&MEYb`XkV3Ds!ZqzX#W! z#?N#7PbH@My94_k7k)DC-siO6-R+0_L#Jb(*ZrZ_PHw+Q?s^xwgBuUj2_HVb^?=>} z(WnjXkG6QpJ@(|&PuTxtw-Y{p@`MvUKeOB6{#l*lKm+!sB*bSj%$TvVpjaTE02(6R zCsG4R51{^B79(PG0E@H1t{pueoq?E)F_pyAg{LvEPBUijbR6kjoJR%LUl9*iP&g&%@Rg<>7-$qlsB78_rOTh0n69A#2@+ znK&3`+PS7>CB`cg4TEi?u8p5!d)^Z#NZfwnM5MBTyzj^WQtL(5t1L&YGxfIBv|`lS zJ7i=_Buq1igz$yi1B8`moH|LG=2c>nR5`}X0Lz>?EMJ2Y=}dXJC1#EYex2zhDv0cl zfnH~A(9)ps>CEg|5qo3)?DAl>p`-? zM=xD@7ttTF#0FD|AX9pYmcocPWKAWm!YbL#nD}t3QOlfo8vOo`#IL}Rr8cAU4st8& z0<4@JBn@J88|r3Y*?x2nn{b?Je5PHZY2qKz>~A&9)%J+k-I~mYx!`{&9M2F@VM{mA zH*MZSTj@vYVvVWKuwD&+#bix8M)Q#fMNNqmO&k`ELN&3JAw@BoPKZue9iEA2&a7mI zX_{3Ih4^QNvdXWMi|iUc4^jjPDRv?e=0i7D%(o9`ySLty^4(kSY|nN-`O|&?{w{YP zTpqdMt3vci?V0Va znAQ~*9sMZkzBY^eLRZgCK8qf`Cd%)Bv4U~7MNs|`(y|_~lxNJLIRroImI8M4SZDRe zI$th1uq`poK0Ov}3}HEseYS1R@eX#6?-@Ht+7GgM^;eelnXF+j71+9>As0v0^^g_O zg3Zo7n5NS)eT~%@A;>(T4O4NZgQgVQjfB~D18Z_Tc80vzTBYw(!Y66&urnDXs3G*G zhb9SMaWM1v(qt;tGW#eh>W#x4hS|K4&1Wy;2&xgeEJX-JYRjg5u3jchIl zV+(u@vx6(=e-AFG;miDmL1@?pQ>EF$D#O+Ak3w#?6SaH_>9A;T#vW?f)4Am7%z4)4 zJ!`X`wfDOFe|YBBnFSH@z-3SWlBa+1*zN6in(rL@>6V=5@x15ptmkp;p%*-iYCPo zkvdQG^)EmbnSh)uUo~|I94ZsZ^D{zpJ_2WxRP!#xtbw94N?ahX5{Ew%y$E{(U8gb< zJsBH0h8cQ@&Yg|0HLiwuod_5|bM&{7ATm6rt<45L&4<{M1Emn1rX#KHv>c(G9ozfK z&;}66vILumH_cmcPqa9&l%}1UB_Z!iS=tbR4x*B=;=O24Maom>H4RUlO7U6v2(*e% z%rZ&(42s3&Nsl6;dQN&erkhIYxf%F15HSkX4C7i#yxwz>Kxl3jb3I|K|jlF!`UsrFsBplH<|ku;uMUl^nJl z^kwR3Vjj@ZrI9)>8n6;*tHBfuZ2H}ofBbUR({ZnLG`o3Uu62LDb^n6zUZ~^E!*3lX zX2Hw(h?_?YgF`C=G5kSicFXgBmdU>OQqJ?$yyvS~&sV`lWSje!n>Q^rZ^|_f=bMMK zf#IxYnD?tKmSkqY54-e}PWvsVzWE_1gMC2T1e&nGOZ_mDMQI0}c#Tc_x6m&Jq5P^6 zJ#Sda5mQHJ%){E@aa!x5VLElE+s{=-xDdy_gwDqD4T)(tz@&9V;evyvgdA&AUiePG^%Xq<5}E=dVlTh(bnS*@B(LvE^^wuy)( z!SYvF2v)Sv=%}&s9$}S|R$D-}j%+ChWA8nVk<*pg{{n7{8EnT421Y+}#z$pJ8Ksjh5c1|?f}z{{?l^LR9r?hHtY-&9xpy@)^CO6)yDw11JjxaPFas`bt#Z*A@IP>_|#B!jG~14yHXldz80$Qll!6``PVjVr=EHS;gmiIqfz5Z%Xeswiodm=$HN z67vs?+OvMBi1`yL-JuXd@e>8CPJc|k%@wxIFf)e|E(VkTOB9<~I+JN2vtHxm`wjXe z!wTi^6JX@Km0V1H$wXIwM4$hPK!t%cp%k;*eG?A#e*hKdjlY89rL5znl0$Uvg?_~X zTn^_GWcY6eejA+^w*rsb`K(wHs$jFr2{on_G}@ell->+H4Ne$v)BxcPPMlD;f@5Nf zvzLw@n8AqPYAD$p&NWnB4nDEN@5;;E*U!Rj6r=+qoIE@M=QC(Q73`&SbwXQL$?J6X zKyg?FjBF^V;qygrWf^xmn@Yk;V4uk1M4TffY{hGXm&AZ`Csn>CV6=q|ehh z@BceE%9iYO6dJbdHXN?7%TE0uG_2TN_;S-6!bLG|9ESG1@3k&yuxPJC9A7z(Hruh!dhXICR|#+w^*9Pw1kW2FVG|bX~E+ zVEao-`T`_wO7wAk-#TtAtaLv`G<;Gs2G>{5@Qb98VT*3XGBg7FFzD3c3N&rnss2ow ztxZe^$JgMBG~kJ+RY;wx$|2EPg5;WBIbf|BzZKF!7>=nIhm0 z8B_6$1=kCq;Ie@mA^tPdM z$Qq7yQifGDAycg=53OU)AP(ylw9S%MTR$~E;271IZX02Zg!YdzK)q?7j~r-(#@N>V z#5dTT7b6g&>brZ5e;~sJ++kx?|7o7AZq|5HX?7|eca~^z!kPzX3#zxA+efyuY>IAn zh#{WF3Ac<=bZf~c9=2GG!NUC5eleg$&^Xm>WWG@CJ`BW5#d#6sJ>(k0br2*(% zbi%YACK$Az1Vi%Y$`Pm9LvJpK37Y^(Yc3 zq@~)iXHIxkJnPoKByqN$bSP7X5ArtR#%#5%&&cMfmi3vo$5qxKd+-o{fgdFYP;BA* z8l7Tj-KhK-MfkS_P7rvWK$bv-MK24U4O>S=Cr~(9!sg4=)NSGy|0U96Yg*s*#v~5W zdBY6Ay8n%DW&?xwdUq8Bj2`B8e(P|~5#yN-54kJKw>-1)z zUCcZZ6R&(*8W$TeWVBB(y1+5gS;k0?W(?t|Pjrd>6}Zc%B8pyPx>w5WDbZ}t$_UA} zfd82A@h=gRowj{iJS;AFHNM!hgYv7+?uU|)p zybESZuFU$NBD&bQC>~lrHP_jm>X2IVA{??0&2U?c>-An%Nn;FtA znC~yZEe2#vyoJS6o6y*6PmG7`cSDZxHuv355m5Qp@O`u$8QXXTDj0p`Bc$iFB1JAn zF#O~q^3TVVQ4KbnL~l4bp)soD>VHOl1inXO^Ve|9oBm3UdZ(u(5a<>{Yv*x8Qx|`8 zj;_M+miZU5jxGGnIkps<*IXaC`Qn|Yv(3A6&Aao>yXOyN9lQCPbL=hz+ph1pDc}Bb zHaMCKj^=}-l;J3UbB@tMcOODqvfZP(?$LaAW$04}K5!Q5n{Pf{vfIW*7tR#}f?NU4 zKSMmZs|@JSv8&|qIzjHNptZ?~u~`9dK9}{$Y=J^oX2u|EDca6RldZufh|itbG2 zJj8F>vB-3Y^7PR{SO!aP8J5pEaZ8K{)9NPN z_u|oO#O`}>fYLZGIW7yj@vj#b+|4;_FUfPx^1=!g6#AyTxFh#*B7)y9mGYX)S zAg04mV3##RK7REVaqgu2uigV7CY>6gLpDrA_x~YROcGy{*iGL8=)y@RQ@ltQTGrU( zRI=2uGf|wO(KXMMGd(Y=xYMrYhKtlxsq_rY9lkytS7b@+9+N?OdAvBQ0O6K+|3AU^ zZIMsal_%qN;oCS2r=Q!pBwQ71>wF--#dyDmfBrB%tHC7bzVvIIbmsF9w3M?2-ZEXj z4Zc(_pD*^rkD7g}Peu?sz)jlid;@R{1uG;W!uG==r?IQEk(yj= zSxHik`X6a^aRF#H)c1nxa>2fQun#2LyLol6IKwQ2*Dm?j-aMW259a-YS^r?6xqZ2L zc&T|f*F2hU9?kk|ymT>;DRV3e-pyDr%zmpE{RKlA|FBvyj4!ykdAt*s0o9EUxbJQd z0b?}u`s0Ly9g6s$aJ=n+#?ij0hgp8DxS~XHqo}V)$csDX>?=!-5XiVH?l2Pc#d(C&zrTlfUv z#&H)~!MNcg8=5ol<)Y>t6z({ij;Fx$8Y8L@ZAH%fj^b8so>o34%1nz@et(WaS+Sv{ z^%W)rc%I_AL*?I77=b^f;dqrO3?A*EM!(&Ou~-Sl=b3PGvh`xyHMX=s5TKu)hZj zF0%)UQD4O<+^uWfKP22;=NKOp?hc6i286qV4Zxzi+wJ7u-MOzt_%I|Q&W9~^`+Dsk z_Sne1P9%4)o!kTB{-FKC^_~0ej*o2Q{>WapztR0sy^Y)fk=%`TatA5?M?@tHIUXQ6C`RVXMH9i3(ZP0dQrdM$AnLQyHPw<_8bc1o&dt9y^vE31yrVCxzsw}!vOgevzjLEqxl5&g2!QqP=lG%1)QoCc_o1A1{SOrR1B$$t z?gZn8EzkfG2LS2vMYR}+rE%8+yQy0x3pa&OU7;0QaZ#jZ@ZlAfpNy;*>of)(*GDTv zcNH&zI!fa+uArAy#Yf&GeJHwNlMJ0hhMf^Cdih8KZ@E~4mI;0VjFU`GRfS|DSO6}P zIec|36TY19d;n&Pu+0C^|AH0-)@^9j`#$9t69F&3`tjdl5 z2Pwt|0*ps_l3e2izD|H?P>EyUs}^Bcg*fJ+XD`3j?Fr?7A(U`Z{Sw9!v|JPmLT}dk zek|0@v%i8cmR zMnUY(3Tw@8L3k;<@>>wlBFkG49?RBx3)XB=M2*3)yYlwn^_eAmch=rraBRx1@P6#r znXUDH>}y`wb$u-7>(2YS=RE~?!~D#`g~d?TJ(zP3=G}wyj)HH^!rq&8IbUDi*EjDe zxq^_PmV_!e6ci6J{|Y#?Rm4qt)nIYg?d?B)JiGPqClvT;ImTJhDZ&n|8Z6d*LcX7t zgBoY;B9zCq;U~=hQ*-F7Td?^`wjCnGan;}x^81tkl;bwvm3AKUJg)L>{P@tbCHoe! cwIo;oMQps%U9yqy88ImKQ_s`{OwRXz0AW!D2LJ#7 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/__pycache__/lowlevel.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/__pycache__/lowlevel.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1181244b635e78d274692269edf6fa1f9469f854 GIT binary patch literal 7645 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/__pycache__/to_interpreter.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/__pycache__/to_interpreter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ed07078018a9911a2f8a8e0c92eb580473173f3 GIT binary patch literal 10016 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 P0~#0LKtwzTFfRLVU9?%r literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/__pycache__/to_process.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/__pycache__/to_process.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b68b828bb04cd5ccd134109617b8cfa4ee51f387 GIT binary patch literal 13664 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%0ASJhvN4v; zy%m5FO4a8}{dulbRhx?d@jO`?KU)NUDZ|q!MKXU|dO2mbm}~QE9I17HFcSft;KN-0 zfy+GWFYK67CgwoOG>gxW^26-rnhG?6YXoYI&6`Vk(Niva*X~b%O?;VBVQimeNnWsdZOQW;EAf=BmdE zEEHckpVyZIiyFp%@(*YpV?g;wZ9y1KO8W}2sCgavERzy3$D9GSY34Nej30aWW4B}h zWGaydr(}Gb8GvXOTbVZ2+eVpvRm^3~jgc-HtC4j00w!|Z>jDIoMAOe;R95ln=+9V5xZt^gOM2?*tmyt2%EYA8O zX3zri&5UBoJavub=;#=rQa+m^8FLILng9mRA@j^NoVOi&cqZh~kZ)ohoqU^Bhk+Aj z0w<-wV=)+CiihMDIjO7w$>f$?<~FeX7V|#e&ohj7GC}v<5`FM&C|F2 zg2O91yx$#t^+?uP@#e+bv*{MW*)BTUA?oNuo%z)hD>~1z&a-3|bS_HMNmNjvNlpQroht?FXL@lJfi$yAzi~q!B%)bbXF~mFFTugXY<3J?SiB0 zP3>)xuj$IVJ-3gg&AfYCrW}s%W@qPnntR57D*J~re%FN1d06Z`EXS@Ij1`^P#+~=) z`SIt3#xr8$nI&DOwhY?bk{F|qc=cI2pn45o6$%UE3t z;|t?57*Ci0kuP|es@jDk$}eA%sSb$Mr_82dB4e-O?X8*Wwnc+{I!#~upk3@gBGeoe zYmP1&7mW|An+r)--@7XIjSDpsV$H;&5d_EBzZME9_2n8f6-^*bW!>#adf+{S*m*#x zJSbKkT$oUPvM5HJ8_QxwCj0BQ6|#1jtX(>KxBY{b`bm&KV z(1RZHs8;)6mu6(Y_Q8HV&>x$Jonv+AH+AN*e(i7CHDf*6-}LA)z0*8irTwkegng@K zyj=U+ay_Q&hV>K8=y%QL!`0f~b+;ULYd>-8ftHPq&zzf&_~v77dUjx{8GD`BYr&om zd-%(F4sF%sXuQw>?k>l_g6SQS86fo}Tmi;NFYNS?Y?@>f#9YBa+&;Le90#OTzCOar zV7Fv1iRleq3^DjnAeDuqi8#Z-*REdp_!W^&Q{Gr{*AjryGbAn(@0}zEY>pYaH$cM& zGA18b4jb+2wu0+E9j0gx8VJdMP{zL#@vD%b;ol7A+EKJelsyhW11euc(u!*?fhmg zgNFF6T?XyoH**=Zi&wjcT7#%9Uz}UkHt^bpjBXphg?p&m$#3QW@8XgBp~bbZYjLk& zX%H<9H^_{|v#<}AElZ1NX}Li@>>a#2!|ymQ^qvrVPw=RMN8n>8pc9$VBOmR|=)3@- z9U?RU1A@;Z_;R2jG>Qi(DFh8@$I$(8e&|_Y@Huf1v|UwHxPYF6HLtoM)84geI-wyj zmiE=J3pyJC$4#~8-A#a5R(n?oq_ZwuU)EOh+UktXbz@S{xka6uFF1gwbTyF1yaQwO Fe*stEx7Yvx literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/__pycache__/to_thread.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/__pycache__/to_thread.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39e631839fcea02f78378ce9498f4c191553a462 GIT binary patch literal 3187 zcmaJ@-EZ606~FwjOpEe|oVKZh)VXcEG}=0A!G;!an`B*w0!6#5NWB(NmQfUWZ8N6s z6)s7u>O8!=5q}=^xQQK?w{*ATYqd(4t0PRHS|JQ_s0170F3UT^$}? z-g`cO=Uo1GcD795`qP(RZ~k$HkpJUDahVyTJ=_Q8Ht~tCg`}-DG!1z@)Ehe7jnHVD z4O7jT;Z(cSC@Fp_oNikU3;2>h9nQ4Njk4mc&~8^66^$_c#%!U=pV^*5Ue18TGDw+g z%(dqm^BUonnpt=>qZ3y0?K>JFcj2F1jVjE}`ITd{i~g*y!*A~2hX0&@>Sn2N!e91J z-!vOf`TBdLcIFVb*R<4jITx`T2ZBde;Msb^4MVpTGT^7zdmZ+^D}gn;uH=WP6&|Xa zEOy+e$33UzdfSZqFggE*+i|@h?!6PVgP6&herUk*LmT(#X(gAno^(Q%mj1wD@pfvh zJ6Bn}KzE zuSf@aT!R1K3DF+@1DLmo1_0XC|GKoR|3!<7b@0a5V;ye!3Xg7$r#^xbxNt^LFq5-Ea?FzZgB)pf*^;gSE(pwv9eX}{1re>3h zj*=HdlyL-=Pa&^rW$Z@VwCe_Oz&GiJkTd}Co@fI)@-0ekE{^#xWxJG4un+8xVx%(R z`PM{6jJA?kJ!W~KfUJbk^B~^kJu2NGV!o2gKJ=Kft(FOEF&b=gAz9(jTE~@cTZLo| zeD?CHP@D62h^95#5fL~cxEs<(aYBbMu20-{9NTNO*<6iSkY!>^M6eix48b3ZVzc?C8%DXV%;k}=B6sMH$~C(1 zNKnEd;>s@3VN$gWy5)|t1~vdZa7zY|k=P6<+ARv!* zfM)a6ELCEMNg4QTB>#zvF%B&OFjjeF(2yd?4}-_3z(AhHyqBy&l(Gg!^BIhF0+@oE zn#ocE%@Q)*77z`zG;=P(q;N>l$f)z6UqB-Sw=(GZY{N~$cqAOs0>b@T7MBdKfHWvD ztO_g^knP5_7qHNelQ?X+e}Y?A5XZ}Zdx-adfy1>z?ye6dv6;so5u(3D$Qo02DBMJ5ZIwGt?w z1}?&Oi8Vow-l^}nvfk}>>#Qwq1Z+oy34*!~U2dly2CaIh7jFsv%hd}P>QKJy=Xe^q zn=GoUsMH@trPE8T!W#KJXm|=$-30O#{PxK3Wn!J^PcIKnzu32y{%2K&x;Fbe?TgCt z;N-KznW>rbHw4JHNQOwhn=^@wwpAJAgg`$YBdq}_s}Lu@EKD%$9-Lr-j ha%N?4=Ir3yPlxt74eIcR$W_hKeyt73k5LuK?*W-Pj=}%{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_backends/__init__.py b/venv/lib/python3.11/site-packages/anyio/_backends/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..412bd56b96da94b6162dcc69752c2ee048f9102a GIT binary patch literal 194 zcmZ3^%ge<81aZ$^r-SInAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnuTcH6#3KFj z@^byu-2AM})Uy1X(vr;lJpHoNyfXcq%q0DS%94!yJYzjWL;d2+l2qM-#N_P6^weVg z#JtMPeEs+&AU`!PrC2{cJ~J<~BtBlRpz;@oO>TZlX-=wL5i8IZkUNU`fy4)9Mn=XD L3^1aI87Kw-Phv8w literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_backends/__pycache__/_asyncio.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3ee4c70602ee1544aa2352f0c31420c6bbc0da6 GIT binary patch literal 146193 zcmd443v?UDnI?+HivR%vAOXH#;6tQ9QKTsA{WL|267`^LiFO<~3Qe&gixNP}4bZY^ z(w1x|rZh~@$TLi0C(?{OqnSx|oSkHkB|DRxJ+pfOPG^aWGn}iv_j-16XU`pa zl$@ih``G*aRp>@HK-zM0&Yo>H3)R*2?yA53XVni13i1uOzWk5>{H!}782&eUP%bO? z2>1S1yTNeP@Pt7$h(g#95rTq1eq-1eG_qe)(8PYtK@0n}2CeKjFPO)EZ9yCRwFm9& zH$RxqejPyv`*jAL_%(%1k%C}B#1(W!+(CE56ZAw1gN2czU{S;y^s+L|VPB*;Sj_yE za7m;zSQ;q{ma%7RxI9u3tcX+wD#W(j07N&-vlikw7rO{El!-WKD2Qq&3*eo}J;fk+xu4 zq&?UkSr=Rv=?HeP@PhFA$Roi=nBNt)MK%OCFuyyzF|sMRiTOR@&5!QRM$;DN}&;K9hD;GxLj;9ea6Oku_Pe#5F`~rJl5q>K2#o!m2zcL(*JRN+R z`K!WTiX0Dqnfa^X9|%6f{59|o22U`5E&M~lp@ROo7=O}{~q2*?t?}&Tx`whhJ`98w`BwY`KA^4`)gV_66 z?C**P5bK-b_r$~ay~5hqhc+Gw4QI9g6npm=-aVdG|F@PY`p2$jW_IHwKGZdh6sP|{@ddvvegU~ZMY)d{MPu;Wtc)+Bj3COmro_uC z<67wLP*>=3x$@e8r$5X*oit|r!9QX-K8+l|6xyDZ&m8*($Fsh{cf>EFPRDtR@r?$u z-hWqo2JZ*d9vMX5Cs5n(Db>j;<$EY4AP(IW_4%-Rg^>0n(!R5N+N|&W?x*DREOI)9 zoG1yq^tH&!=?9;Z(=c*6jhwDOR8H5$cf?VQxEtcT;&b@@W7aMSc|`He)xoN-P4Fg* z6+^5s#CmV}l7jECSkEKYIn?J*SBUkeEY=H%bv|o6{~3ETjyErc{tP+XQgbk49^s!~ z!CNfe1maC1R#*wos`H<-ST7;g%bybKFIcP#h;xV4X zYl!s~R{tNV@$~io5sUX##Cx5^`!_4Z`!{U7PwB^D@UO&67|)m0@&0>R@84(dr`7TP zHI(!9&@)-RGr;Qb2HwqtPGr3sWbeL#cW;JHX1xosci+UjE1@rEy*tk8`&L$cek}ez z>id>jpQ}haoAu@YEz9*=c=HFLLs_~0HGB7Myt{_J|B2dH`c>j5EY{nI^@pL;SvmYP z^wZ$K6OG3Vf$#r{k_Uv8V{l|-G&UF;9vzAH1@cmbohPC(X>cgE_xaFB?9k}w*_5km zaAYVH4u{0Ok~Au%?1SO(Kx{C2CYo{#Nuj}5h&`p8Lt~PJMEuF~Y$!G$jg5>9k32gN zrhF{Xa42*ZWtLF*z}QG^I6N?fH9j0d7DFcj#+2iTB!;Ar*gZTHOIgIwb7P@^E#>Nr zo*x<77a9pkgE3T~fIaud(vSAebA!XN!4u(7%GQOtF<*YyC~7=J?Mm6ZMy1iQ*zgD< zuv9GSG0GhcLxrq8W3e$QgbI`>&F>l=iG^N>9UdGRd^RMdY|*i^XQfayia2@ccWChF z+4E=ti-~OP;$UoWC_KnxogI{7!-L_J<(xElHX1OeoLxtb9vL|LL|$Du(*cpADr7`tiv_ zCkBVk&||=wGWH%p;1?g;JJ7X%Z`VPpu&Hz8e9Cs@EOjZGl}9n39F$V#p}}Yj`4)a5 zGMWaL#VVD9XuQvI5#St2}uJn)|Ql$|At40r~|Ai?;dINOlah2C^|YO z4Tbo)E!;B}J+BY)c7;cyAz%vHc#gdz;*pcbV(6tvD*p?kV_|U*az2wPqRP{754|uH zV*L?O6LbgPn^bh9Kh^CzBh!FJF8a^ zWMRDlkC}RbKBQ8!ePe@?nDQPAMF!8F8kIts9ztxp8jJ@ApRLC*HbdxpCz~sK@MS|I zV#?L~7>xxQ9_+ij_{cbfuR*gbRq#ajV~JaLQLTt!e{2x7ICeHPbi*h;MK2uu1(l4-qhx1#O!kifrlhP-j9}QE z!OY87r%^Oz4H00Art&i%F=b)UjA}s>Y_IZl_W^309YP`Ml}4t8dld+}Y6uyEf@lC? zEPyCB2F;=gM6ns*)snIf&?gF|^7tSSF_}k(2_6iOhs2b1h>g2G3{~5}z{p@EG%%3L z9~g*?ieq8&I|l}y8ygI#-{f^2-P_p@AmQlk>+SFDJk%S+gSG3>kz;$iZy4@T{T@8g z{`{cSe(v14c69&g;n4G=VZgl6k#@BA`S$SeiT1PSW2Z((9%<|7Xpdqjuch7rbc?nR zj+`GJZ6Bcdk8cuf9~dNnJ3QKU_Plfwc{ArFc%s#CE~tOWqROefWJ$x6BUxBJWu-sq zIVHZX1YgTk(t!M`>W)}ToA$~1lomhllt5`4k@SBI& z#n%L}K`cjX8{SqR)GjuP)%eX91$6x?={Sn$yJ4jD$DQj zFkt|Kk-jDbJf(ZWV3;uCNyX(vipl6yip-v@N;;9!<*84U&Za&Y&}LJgM1}MO?EG^@ z@PH8*Wh2l!!26+qt-?x2q%3?FEgp@s1g82z{9Q`2*p>@$;+&Hw5V-Qby@3rrTy87y#J7iZd|oQ5%;I`6k6J zg>%7>bb8)6a`{NYSuH!OT9ALrOe1zk9W)412jS;ywuoj+^i|Ms3j;s~s(PB6k3`G!F@v4rs*`9^h=F0LToZyG<;Ld~=BT8c3*qYY(!SIWkL=uH?o8YX04_c9 zF0KBQ($oo?$-!Xw^wLJ^SIRHu&E%5Z=IlD7w;0=(Qb@iS4b${>+Nt=&<@&8ad8_@^ z*BFc}9Z1uCIhT?S;7ai#{xL%XeZl{M>U7TVg6WHfb3(v0UUTf!SWFx}H{u^05&djl z_!<23(<0K=mnx5@BLJwL92^S+JiZVb8pF~Oa7*K8CI`SH=pAC&fQ+cNbql2-SBweA5DhAXj*+okisJKCj<w!e;A-VNX!gpBq9geg6t`g;!tvw&a zvfkhImdf7dC4*47ZqZjE`vTV+6TWuY*B+}vs3YcNR!Idve9I-P;MEfg1%U=F{z zSN0UcWTAD4U0Cad@yerY_49`!Cqkka615{VV3fX!m~8AxufwNZ!)!#7)Av``XC>e- zC??^w_~N-M*p+Qq$ruQ~0Wvd9?}F|Fwfex@rO>QT_Ya_ASiz2`Y>IbC0pHXDEB;yg zpF!6EUs78IFt7Tv!CAB@rUBppH^R4#ZyWVM?iC@XVn@h}I-Xtnp1kOe5y6nYL{oMi z_#RZloJ*ezmK5WKJbV+i#7X0Xac)`gj#%pAlmU2XA$ldly`MBK50v%g>f)%NSs!Q2 zAVp(@p{K9Y>T(sUQo_(b9>uTk0bQIzB@XiJjjd9ifVCP83fWEoQqxR|9ns z(B-byU?M9$p%+>+4LGeX+vtxSgteYlTP|A8 zu>O+TV;z|k6DH9L1O@XgBSD(9Ojs^f84VK_{kTC6Y@SN4*dv)7^l@GhUNI=Wj|KdH z$eufg8Y*=RRodS_JQ5uiL;l#Q(6X>|yha=O++frndI8*qSV(O3KRX)p z_l<8(uaa26R|ou9*ugsWp9sN6+)@8YX*7ZY@s^mL8n6r`+a4Jl9$}nOMyjQ3V5+nhwG&(YX*mxnm zOf~p@a!!y#&^nce%m{T!6@npnVidfqUWK*{SUH{X9f~|hk@7q!A6 z>O;X*{us~W`RD-9?QLl9Us0q02JZ#K$KGn$OKZQkUG}yE9Vj>?ESC7=bq79Zgo8U# za!@Wg8223f*j+5Un-lJU><+};8$T|oPx=mjVltK%{n`L$$zUujTCx!lqb23;x=W^B zPFB=hTRW4N^j2Km{^s`C*tK!FcH^yB!n;HE?wIQSjnzE8F^>yFP+7G(pb-jtYUb(J!#?p9!S{WM+Ff$(u9^MG(%N|Gnp?J8wm;ARVgCDrf8oC6UaV`%9kRxsvzqM+vHaxVE;t!0=Ilv%AXlQKdj`puERp_#02BV_&7|=ar^? zHHM$pbh`JiHR(_|fK!gb%mZP0D5}*UxwXhiHl_6n=%*DZUv&}0G6U6{V+8b7ROrH^ zF%=2GlCB~ndZ4Xk6d|>`JVyPx)G958I4UBeM-FHSMs8{jBjrGs)Y_m|)az4gpdw%w zYqe#~sg$Ui4LpdU#?P)ztTGexw7Tr(l$}}7*#gJYWDrChWr`jKBTeD%_=lsM{uBEH z9t~wjw3Kv%oDp(}^_Ql+MndN_yfO}nFVJh!8jxOuld=(SBUW0qFq(0uTF;TKfF4+|KY)ZeCYu3fx zbTj%5fwH?U?hY(gH^|lN6V)5!>J3C10W!#?YY3vO10*Z1WW?0XmV|Gk?AsXkZA`9d zpXru;tMA{fu3M;XpRaCDRCmbL9V{)?Bkpbj$#o@v!P7YJX`JhS=jnu}L-usUJspcx z&2rU-MAas_Y7_DI7AyR6MJw_Drtrt83+Y|7=z&vVK9l4}$LmsO-#;K8&Au0e%-j)$ zam8$5`{F1vv;~eL)wfe0LZs+&kD~~Fp1MVJn1Z+x$_+Ph#C99wj(?k zIUx@28gEdBkGf{J?ckEKUGVTo{|!mlYJ0)(zWIWIeGaVDw6>?rBAAX4Suj2Z=W6%} zIQdJ)UqjaW5OYjn{>FTDk+b0)N%^7j234d*tp?Yu}RHX%8$J zR&uJ0_A+2bI>%3K^edVk zE{6%DXug(3Y72(xFA%&6So%_hTzaFCqW6z?jE!&t1Kcb{{OT9SB%-5~^#J%js4j&I z3Sm@U1Ue27V5aP98i`bmFiD5-BN3RCZj(dgNy_>xB-Idd+c_iy#U}lG3NK;6OwB@} zKmsN+(&Qv#viw<5scF_9PQbXbYvw&`?lwG`Tow4im%sbv z#Hx+*s*Op1<5Hfv80b2jPfXTA5I}G+r3;I|8C8m5(@8gLXnX>c2=|~_ZFt>q&>+xy zWS=se6hzBw&PhSEUea*=FKHNj7mQ-wF~cRp!>q28MlJ5F!P|rh<4NJBP0u=+G-1tt zh`At;49WPaLCky6^rYdc>8oa};--h08^D55cd$PmGPcT$$RBSzHgqaP!hObmPzJGo z^dx&u6WSR2T$s?7vYuorNe@bt(a)cwZCq7p1!zXCXBfiY!}FGK6)nAFq$Px3%VR#G za5IacDj?PJ-v>CA3cW;wzW>oXnBibtsWb#*-!)ANpOTyUy|US&g5itEZ&G*(8WzXW zzH@@wqo%%oa8=Bt`2{74!W?l7G`7-`8tD!ipUNlHTM9)XvPs$ZDj+6Rz~m*$Bc^Cxd4A&H`i6 ztF5d6AF{C@P+k{HfF(Qx#uEkC0F;gfpU_h}z+s*vY$^lWrBjf4KTOX3qVO8z`5Ta=#OO*u7DS1i>$Dk2t!5zv?ww2 zr#q*mSYalUSW(8G5ejL=JNh2d!&vA$lx5N{|Gl#7GijbMOPv$u(<;Y^1OZa%geAi{ zx#-b8vG;k}koWNZV(n+Q18G#Ai@xUIUy*v2xi1HiU<($t>Z;*c46WmNU&7~~6!7_k zZy2X-Aac**C3ArE8Qa#Sj6)|F>sW`2J;>h?h8`m+6z>|ZKM7^m%oNE$911Ussb z^94h^Y&XBZMWRbAONbAU#m!6?1Gfh#6)=6mk5&N6#YDJ+^%(Vre_)BWJ15hF+jcWdwKX7U^ z%I7@RJi7`27+y+fty1>?K^YTZg~HOm!k^7YPr3BnBi%=&&D0-9-~fa5R9tnv>6(ot zJdLua@j`Dh&lAt9n)_k~b;KhO+qkWavAnS`@OVmLF#yS|cNR;-Kr=w2+XnU&^t z-0~$#H_4@&-d{Ukx-VY3?_*!h)xJ0T<~AgJtHFNh&y2Acqtr5dhX+ENuEvA|vT0iaPkP!~36B4nnN31RI4GJ;S*!Aw4`+bfnWtv|1%Drb}$1{D^Og5 zyjaS^*rCr8B~BvHQX2r#8#^!WytI3I_l0gi$GD@C-=G96UlbPI{yAU5-6Xr4-rMoh znt03pxO;!xw*UU30}M7JVrbouU8V7|!?(KO@H^q^lU;rB{-@%$rR=GBmtHzr&OozEreqTS6y+5eHAmIj0{uAd(jE@ID zTVnk^V0shnoXQ`LLR}z6?<8VLgMcJDC3{@U+UF z)+GzVvC0(suGnS^uQ(PwP4k|ncym|6(=B_tm-6U!K9tyIHhkm%pFvk zZ)Iu`IcNqYo>cA;(?eEQrYwUA5EWX32|THC>`yIAr5RcM2%%?}mIBMrRH89$GHwT- z+%Vu$Vsq|Qb_nR89_eYsVGt?c#tN^Fl{|1z*kHLw@BdFYSYC!s4TnWe2Sih@G)!Sw z3(ScWC1bF(5j6JfsTe*t3|?S(1tShp7J~U>ny;Nn%o*;m6QQLmD*c)YGDXjW2!T0U z6qZA19UJD|k2V(~l%>9`bc0h`x^35b>4Q zO_`@%$=y1u7%Gq=Cj;6SyDY<1UnUMtI?7rK&PV>aat~we~F%=_!45L!7 z=K*~V%_z^+=g_LFYH_6uIMw1tdXS`F#$KQqqmF6dY8pL{6%O`4Z@P^~%OUp&Hr( z-ZByF=?kim)xb0fSxa9uPxXCBt9_>9xQ5FO$}PQ6r!q)I~=s zMjo18RwGeuFsd?C74-lX2xysX-#a*T%CDIm{>b2Y|L92gJn0jT!6wyz5*X>AA6Uq< z5E?WS-qGwoL3XJ90k7nzImgsch_N933pq>V5Kn+S~}IL2(oYzokjYAA9sfKwR2MAG3h>G_|st6YgxzJdkAE|g}8 z%CRNNcDz{AUMwqV>#09N3DI^qfCgY2>>xq0Yq6*%=^>pwuM0YPUKeng0@rVBhUPWz zZN9nVr&T|$`AJQpX}{b=STfD_*+A0foOZn7zU-d0Cv5eyjaH>4qtm`~v3%9suw1@w z>HzSh`c}Da3(ftSWK+x30omE0Xv3@}B&!%|1F~n`f@j0LhqU7~40-k@u;A&K_jKF} zBs@E0&yKif$Nl@iDK>bRXuN|kF77Or*UxPLy;$BRm$ywFNH(qe+M(Ij(LPWUWY?^mMaW3I(m7T3|XDh5S zrW{cka<^*>x-5ndEsb5RrVrN$aG8F>gNkKL%oKyi-$S|wKAn}B@{05r9{6;|;ELs= zy6_^33LcLl^s3<{EO@68%&+L@0Fe4ghFnz83Ue=gK3O6vrZ}g@=0vPk@U*-jP+Nk2 zY7&$5q8&_972r+)PtU4D7JWiwvuFnBRGNzo|W692eucx5HkaMRdu_Sa@F^ZJ}*t3mIvILulQ;COqer^8vv+^FlpPD-9KoB z%3hY9L!C^`L9~pQGIcUFM4SJub)p$ea^uBEW6hcR zPGpTy2p`r>T4MoC3~Q_<^Q2#@q|(^h%)1GzzV9TPXvNq-o%l7~CR!&g(;cXl8a8U2 zus9*|Wur)K{Y%*ILtA%g3!c=mz-Nv&B-01E@3cLn%`>ffr}mWy3z-4+DYr&Mk2mDh zQ(2M&w!ZP&{!^rZsin>FOxzxh*N*psJrjzY1-Hc?8-?I}IF=QgbpOTSlh8}ULgS}} z38MDF5kDd_-F{L?N8;g;@&4Sb2KAXCVGJ6fBhAPN)&psMdX{Ol8P(()pXk!`NI%7w z;v9!SnP$Pxtk9nzg7ja>VT*Ge)N|7A!9^@GN09X>wgReoXRw%WMMWrSxk|u(*n;Zu{5^!g13aJ*4fjo}nU!qW2 zIhd|n%B`;XX)ALm(GcTpAbJi`h*4<5a%*PJ79ofRRDdofN@vPz*|Y(-BmQ?NGdc^b z8@v(N5qrr1ae@}YJpyoocQ782 z!W!TJl_+pw(f9bKUyi$5_`O)sv{2D9U(s@X!_D1^itTd6cC5UPinybGZd7jC^NYrK zQy=bhcFj52t+$sYE6GOv5JMdr2sdeEvi!yc52@KCJZojo+PG(JvU$yn83L5MPS5ng z1!v8?vj!#uFDIPsva>zzY*$eamYO3To98{7-#2R%6`>=5H$Xhr&U@Bg7jKRxJiBDi zuDEB{-8Jp*LP#tl^-}mkgB!)z>%3Yo1`fyCoHJ z$s?$A;bxd#UOBShYn}JCCVXwOuMH*u2#fnVWM9Xv#}mFy+`D8kKr=X<2-&u@$30E3 zfrxvX7Hd0hH79Df$+g=cK`G|WtZA`w)!fi~yAqY#5LIqGd zxGWgB&Zcd%-E!6Xc-8v58@IwG4=EzAjh7yZZ#ooTe<k_mn&7_<4g6^eBBe8x$TzK(P%JCAB^#y@Mc0kzRL zT4yp(ox`p(h>gaaTA4jXLt~Ee&AIe=jkf#J3@TFHP#I_1Ef|SccfH+z?WuXks<>m-qPHR8T_t<5y$C5vp1*wl(u>nC z&WhJY=H0DvH$n2NjyE0OD7aEE!~X6zuld2mcPDOj|FG|a?vD;9nvcrOM;Tm?dm3>s zISkNFcW@PQ@LMG^WK%7lsqNG|?ECkjR#23LZi7~YtM7NHt7xVGaLDh$*3}3`hB-6* zq0Z}^Fi)63p?nj+8eA93EpFYG80IWI@66B3Z2bXx(I9P_FiLA< z4N8w>o0Tk2iJ)dG9fSOJy^R?}3l6(R@|exD`aFT1MQj659*p?;+}XyFY%T835ODq$ zN-d~6Vc~pPV*p&ue;ZdW-{#L2Bd0l7=lvt0kO%{~QDU?qvNVkBMn_nVBiQlJKXiU5 z9LhAlr(en^*z^D46ZA2hKH%eAHio4;2O?w8$>DY3j5iYgLPQ8n#{p7L4M`lYW;{9) zpm2qu+wi4~!y?DQi6-FgOuvWO+(@K#tsv%|l*k!9McdSY zG>A#(0XaE6!u5izyb{m{8iGzyGzS-_62|Mgw1~lS+`iQWP_bzfN%cIjig^OHwi>t*V!+w#TdX-7Tw$bNkkgMA;7R zy$=)`m~k<75;5A3k-Q!5)ZV1G>-!ZXhMXr{AhrhjVJ)GnY*WCputv1wDHX^Y&nWua-$eA6C=jJDmf0tIb`x;-3P zN*dyx22_C43k|@o;@fSY#q4_j~h6^ z3~4|_U%2Fkel}YlrMb?RndRx=pikBz_^TPB)=X;aW>6mRMRkFsgi+? zqj-^weAQ8)Mu8_+u%Tdg^n1ey<$MdLRq9XSa*hOb7q(dRq zss9UBz7~DVp1?pE)Q^jyfl9vVv(E}XKzm58Gh8dgcg#RlO{Biho6MW^~Jx9Gef~>GNM0w5Z*te># zk>uFLwEn>|S_8?7?DQ`G-~`%-6TA^iv2B_5XxR|j2^U>skA{siPP+SVx*CSi_}8m2F)sC3166|i65{LdhxJ$31Dm+Ho?s*+Ghp~Y>$Vc)*X+8N^OcQ*V zsj6T48Qvpv!ckc^nO90QD)NR|qIu21083096r^LJlqpZgLW{FaqIc5!UF4ANQkI2u z%63)))+@!%ON>24>>$oiV2CyQI=872)P87bg&n0v+RRaO9r=tzNj6OJZ_29^UD z{ubDQD~{%Ullq<@G!+6z^S+ASJ6}6a3b>dnibFBHIidXP(>EW&zj~zsjBu|8K^fgi zbvtM~b~UD5jA6qP$d}e&q>RroM0qbZe>w|WM9{LJz{g$~4i96$bS|VKr7H<+F(_aG zi3XVsC`@uMkgHJUAli47A=mvR(Nc6&S+2t|+MO2>p#v6WhNcqI;D2P)|135ThY?wb z$~ysVFo?mT{$bjCKLYU>E3J)X0uvj1nnMcWlmt_x?s^V;yGx;yPY(VFsR4TRl2?#)yoh>) z>945!4u6;6Dal7k)2yDY{#C0iCR!`XyV8}MCSo|<@>6nX?C>d`6{W-BF%hF6SQ zl{YQVS62(-4Y5mW=%+79&z%HUTBD;9qi#-L6B=#*jA|jx?SQdwyp40W{LPG45E7gH zv2(*iA%zbY#g;J~7~*|wEE;f1I1D3blp;gy(6HJhDA2rnfjXaxAgJ`IqS$- zB8SP^M=2?jwbNi##uLLW$e2Sno>F<~8jV*hGp5q-en>;=yGRNifzit7g6TsG&W3qs z!`$A4vqg5cKvabLKJ0{KHm zD~Fe)rz`Z7L)Z%hM}hztD!bgnOhXI}A-Z~{p_Fj14?!A0SR^wrwC|eJvlk3GXJHRm$PAaI6`axASn1VmP@+up zoNJL5(sqx^Nj)L~=^Wzh739HJVAgyU{QiQ*0a-D?iY~C>M)gf7dSm%jw7A!;r^hm_ z_V%tl6jT#uH~aWGJqXAw+&h3w`NktUXo+!>d+B?IIGoxZC8b=6EMEZ|SYJ#b2hM=V zqR6o@4GgCBR>ytn$3|O77kx?A2Y-X%%=>`0G`YC{^Y?^ST^*{@>KK9K3N6V<{h}4fTdl+L z^5bm%Hz;QpC{@mugiT_nVC1N-IMRnJuQ?kH(6!UXeG8Jshmb(x8xvcAU92?q37fwd zGMm4Q3}7|Zv>a>j(Mc=Dh$XXfeg2-s_h@|B-jxbt8O?k{w(cJ`QLs*81;=(M)|ad! zHvXI0428{ZwQbs-y7iWbR4^dceM{gUjs`;q4tF?bw5s3S%yiPdFtCKH*=JALg4TY(f6|E~xm2k~Xnya@+d8aTiNMo9y7 zQXD%rY+yi0^RDhjgwTvGWYg5<_a%PRyDMKzc{S;VWhmVs4v+=xt2^$+2sw|Q}H zwy#gROCU;Qnsapvp4IcpuDfwh3rP=~p?y}$_O`{z02`UqtucMhz`lfUgY4T7_igw% zqYJWRY$dr)=@o2LP*K<;ES5KZtNI#5jm5>=uD2v>>aU$yGWg23!Qg0N8V8zZTj%m2p2R*}a2Nbr=KWg|{%x{< zTim}5^kL(gx!sG6ZP(BJ)Rk!5CpYecLR#Y^AGdaX(2!{Dkz0G9nAi9S~RHLZYEd`**mahMj2@PVcV$LVjzF(7*30uxb`7IOc{%_VBDgz4@UGo)P ziHf~)#ooAYnfq>SBlZY&vdw_O$*~vK|0ds1xi(q0_5BU<_JhEBD@z~?tt`1)SqrSU z*bnAR3Hn|rtWQ?d%^U`!y|DiN$6kn&A$`j@EW^eH@7j6q+V{j;kK7o(IsCr&{ULeR zk%ad#+4~q}0q$w-><0RSc&D&zwq(v1uj}A9j(;fRn+w~KF*VZ3Gz-&tUO)AI-UlTK z?|#|4|E{Mrll1;fp7P-Ah%0xLrpRlZW&0`&x2ucywi|A*uj{Tf-SHLdsW;xK6Ubkm z-?htfr?u18wbkqa>g#XRv8if43!n)6obD?Mhga@r%P$r-q7M^~Z zpNaOgvX#(rI_-*PCwohK4IF3o&ksstbcR}P^pu&-B$G-Aj1= zhOszaGD|($C3j`@IlWTUWS$m{zGT+sfjX%5&KQU2)9V+o39Fb#+KnUSpEsY$JZ#R7 zg<}{fz&qIUanhzcamc1GHM&)cGGV94to`t$d_SZEgzei#vEc2TUY;;raO+T&EQ`Ytmv(37>;o5Y)J3&Y3U;kl5d}SZ zKAAs}zr6C5KHdw$q(j=LRkoUNfQ^;4lT)lQQz8_!+Oy*0kZ=7Wja;2l)r3>@WH7SK zkr$H%_(BB}wuyWkeo?4TdD%5ms5ADkAx@EgY+QE5)@154k*6J9H@*6}+5;dixoAXb zV`t1h=4kJvoa>THKU%P-pT<<=q0_kLGTopl14l>z0{jX7`GwqFpn!|}aIPFdg{+Ni zbrc*;C+M&V_x=G>|1Fc=ynVuuDUY;FGRnY;HHtPYBiw!-0yf&nWcjyqC@J^K)nd4$ z(Xm`U&83`%$21vF77Y2*DiIov`HY5K7iF+O$&6 zT6!v*yPQ2*m0Hp-@p{*H(bfgbLJPtxvSTLk6ET2kb6*V#(UxYft`0!MlJRT*6>a0B z3^Cg|6{GTiC5giRJw+ji!pWfm3j14n{D2%HjHH*zVbb5*6qY3C1{_c<)AWjLj~Q8# z5<*;!jP3EmHoPGIgdf+13+YWj?X1GIBl>tlzryTm8;G7AJU5crx=M{y0l*X81;XV% z_+PL?4$0-MFbAfyN?PLHP5g#7+3W$i>JhnWTilzulg<*DCxe;1;Ov-pcHCN(aBh*E zTjI_wP(;bt6D6FDva>PnY+UqI%{~D=LZ%C{D(>!hzwswfX6k^*sj!?8KrIWtjq|>Z zx5R{RyX@N@XE#m~sgX-zN+T3vuOY=j{F!b-yUPhFwpt6yk|mW_N8cPxlr+mF%`>JM z6Lul3BUBtRX~n^TD|3bKRR748DA_HSU27LqT9dAc`)Bc4`N9Q*kO>F9yH}xYV>8qIOx$9jO_pXh1bS-r3 zpYPb8=r|yE96(5x36fB}k=g#NUMOpyFKfSLN|bGo%QnQzHh|`kD_iBtE>ySp5f&-1 zP_}NqY+a&kyxrUPfP9Fw7F9p%IBXbZ;S z?JX61yoNho_nuXzJB*gVIxmaqOGR&qMN$uftBGV6M%I04^UKvm;k%{e3Z%%`gV~JA_(JF1NgtL($1cY!E^M-7k zuHi=_Wec3kN>XQ0Npp&YpFQa+2_0QiSIb6)M{ySgMd>Jy^q0iC_j3|8gMKK)Er~ z%|giUAweF&VfTQ3v`r)qjl4*)iArO17jGYd9_bCr+Ir?3ZM)0GG~Yq2loiL&pB(1< z6Q}ahm4V7P@3d6u5Y*8}BU}oCDq*j|F*^B}?_Ewy)-wQS^v|zH`QFAjESMnJxTil0 zrg;f~1qp!N2MAkot){KVKilaSAfqC~&6W0Yz@#qnVKZF^sC=t^>tb2O+dICs>)NhF zS&LlOGS$1-xCs;H-92+Lxp|9>-L4wDZt)dMfR=K8nW_Bi^?BuM&t`Oywvm4kH z-kd1gBA0EM>IDp(ip})L-Ho$P!ofXdUUcK|$%NZ4yTL}VV2_D5K*IMACE9xBw%&O0 z#?s##FdjCS2>RBwRB%9J+VYY{WS+6jMYHZ|Q?qWlA0+YQ^pvky7Hlv0$?blm> znc3wH2c`V9>jU$TdwypCZA-C30nm+w--RTA=~^5w#IoIj(bViT4Y;G+}4uWi^H6-Rm-+&sJ0?( z!B#VGtC>BYumxmWAZ`n2L?Bl%+#h(d*%PYh9d8Y^%wuvv^bQZ{@Xg^j_W}itlM3{- z8AqPdCmu_Gh}-}_E+Q?TdJL-kJs$OEl%zL(V@4NRaSsEPEOeBnhaU+sH(+{S@P^~E zW2SqyaSrWHOM4*jQ4}E`RI7}bwzjrh&dXY4q-!y8NnWQGlZ2KFdbA?L3}UHA6|tGc z3cEA&zQM7JAW{BAB~vCL=bSKWS@~=qcPmOyUmy;EZcSL`)HKQ)`qh`7wfkev?(!QU zXwV9Vw4xV1GD$HfEZTa}cl-U%dR{?1niX4pDnD;ocy-H%ytAoHlz=vb=U?N9Hf?tcC6Y1FZnpR)X1Z zV1}OAg?zEFYOXt87)TTblQ5)puH$A`Z)Ue&+@PdX4{@eOt)7R?`g8!-e%w9 z&bwoB!hgqY-s5%L@tVkAB9On7`74}=f2Ya3r^SA!#YFzK0{Po4@Jl~Ku0Tv)#gFs? zzL#<=(262l7L(+-90cX_f$~)(<;(u-Fn!3I|*%^&I0u$W9m zHXZZ3^qznk8k&WXTZ}DEbQSqb5UH)so#xDxfPlMTVoolfsgz z$bw1mnGP4nQ^SVP9Q87BpKxy%Jg;l@Mg%C&m9leBY_Bc=ZY-paGNgsiRBQYT_W(xOX&~CQLl3j(5F__m?qm?GAR1*9wvS`Fcff#v z$TYJT06pX=iWwig>irdDv`QCY5EzSP_=KaW4cM zy+{1K13{!n*q&1wz-5_sV&CKk^!5fhlZe7ekw*AZ7WDmCNVbhr)wVXp%;$uV{tfj0RSP z@nY@wS9NNBA05v2j|D~!WiY$zQr>jlf~{=cRu->$1beb4Y#U_ThPZ8mqV!r?L;H#) z)4H!oU-gwE2(V*;DJYt$yR;wM&su=JOy?tn#CaR%D>f!7Hp>;8NmDWjYftlZ!4&@Z z{7}`$QrM)1j#QBdnlK)U)IojqDm^mQN$q$fKO2ukzvUuN|9gy~|pcEsW=36D~XY$X|~ET$S~L$Z=38v#~k!lqXlMGZ4d{e?Mo z%w}?>nWV>rIR1**>X_EW&f0h?!zv^OTutT#WNC1iwiY~wLD>sK2d4HNC}4wF`cwLF ze@4zNa@d$>tTV<=b092Lpi9V@Xlw+Nx;e;o##tl&oHE$iIQa|8%|^-dXd_uDn5jeE z&xubL?3T~MHZ*-c&v>PN)azdUfX4n$PzKwEcA2pXL%K;I8Fp^oRlVSBoOcpwqNruw zbr&zVYv z`;x2I%Lg*g;G+GxmP4uuY)%MY0$`dnPMRjM z;~8{sEXzwRvZl>t=qTmk-!@^@N-i>c+u5-b3^pKDf&GN(Sz*HbUE!$V>qt3Lo+F!Z zPTD8zlQyQGV}Hrcqy+fQNC~v%Jd-!#)XPks$x}3Kw0-z6%Sx1XF;{zih3RU@>^(7I znaG>4=?N^s@KWAOv@3b$>lCQpUgOdCB2o#YC-jo}CCf|J>3>;XXN$fP$0}XY7Uace z^EL9lM^o>=l8?>dt?;FM%37u9{Lrod{P@UedT+-jVazyNlEDx&&2+|KW7C~+FUb(0L2~ zcWZ9>epsF;*e(}9A*Yg^>cm`Q1)ZE#T6tys>Pv6FlqhYMOPgoRPz0ITao1O|+19fWttR44%T4WOdz4Pjb_? zncn1g#k-Pqt#hUCR9^3o*KNgi{B>LTJ!_q{-e0VQ-nUS!agvSAv-Zp% zs1s~3g&6q7vRfU9SM9`o|LsHMDa+j8PhZ=*P}w$L*_NnWCs%@1Zz`?;pZc18p={H9 z*`{QbU#@DuRq}qx2j$?9mDB!O<=9?}95Baf=j_;}NI8@@;c3F5W3+#luWYuNHYvUS z{H=+ljnu76rtIG1T~9UDcG?R5Xg@yew`;ncrrXw5avyQ+F&gg(!kz}>9b^8UGRqyO zagWz>$7P`quZ2R&OysY$A^x2P`<_g>z zyhO<=dLiS1cG&?!2p_*N_b{~hwY-&luH02OUn%#TD_4TdV6ckzE^iW@n~LTz;FT&{ zWC!QrSVDq!#|#SO;yTJUzCP33PUWA)CL<%Gq`)IFOf`T|zI1OO-w#k@(5V;kBmD#c zS|ikynQ+tbLft&1paq(U=aB>!Gi78lT|n%-`~_R}ysdgxOxPM^TSMH|K%rpiRn6Pz zB%REbyC!=fGp){DdsV9l5;WNhGY;Yt9}?5SUWmaKC2{CaD>};!x6AW8n{gVQ02e$K zl}zHTy{@+QkKqG_tRkio14AoerHp=83?8Uoq@R-WDs>a1ptI@XRKelSrv`ev5A7Z3 z?>)Si(+3PP5-gKGKx$HlWT-q71`L3C^ydgA8wmsFu}g%}G3T4q!C>o=P*C|x`bsVw zh8`iAO0MM8dn~{o^iE@yg$}&Sad+fd(7zAoaHO892O|nj6`jTTG6Py_Q$1vE8KU!e z%BxLwjuWus<>_PTa_HFOLuk8tp)=?b?yZBXqpdwSIh%~r3K@NEX7qKD=q9@iMop8c znm6UzLz`lQ#Ci-Upa8K1@L>Mi1e;vO@>yyK?lEADK|1uLWo|c51>u zq2PNy#KofKE?(};gxuZY2&S?6j=)2QcxtghJ%;cwWD}UJDm=<&)dE6N@31R_N0_CX zG*n+fFxMs~(pLc^Y*bSfb%bhZPV@Oz|No5aneY-rebH8sAygqifSpntd;J%$N)$I^ z-yHy&{3-nL(MYJpgB>cnJXaA>%RTQOI2wvU(0Clng6h{W*1m=2JaCD_L$RkJ594Pl zY4~9TH6D1lLF3bE`XMWVl}lAuB=GPsq^q{iwd+VmH)z6qGiR?a4a0=#k55=mlI4S1 zljVdOAn_Ov1AOWWXlKd?Txx)fHwR8iBnaeOjw;j}!c`{0WFledI~19pSO?`z98Si* zvX+m{Fgxly-dEI3IVZ`La=~HR>MB#U;@URc>h8JgqXCT=R5{`>4I&|ylu^* z(@R@&HpPkQru!@<$fz+_)Xfq2jX|$-aIi2WJMMv7hPiiA3f0;4o2R=(!=3 ztX`-JUBbOqxEVvZCxADFa3JOmgo;iWx!IUiu#27TV-Xzyx$czrSPZPQ$WgG*Ledu` zGCYvReF}c2eF>9Z%s9mT6^a6J5gB}8;KX@Yy-Os~VjY{ZumDx=MYW>Jy-Jn)5#l$r4ZcjBF5B>F$IU~v%BhN=W2hI1_P zu$f*62O^ADY8#vGiMI61Jd_lD6v@)2V8!KEzO+!>G+*2_cRo?vAs2T*IVbC8M<|}h;0g{ei%J+m=ITY`7ng9a1?~#-Jzu2#D$Jq-v!3>?uw%A6mD&CUiS{yFVYc&^ z{7e5ewUG4{M&~jX^i&hP5$;XE^RVMKdva&l$ZP39|`tMM{EFm*lB7R8%V`lkC)x^7rj%-cxw#O8;pMBL_2x{9X53oie>%b#%7 z%Pu;oWTl&ZOdU2$EoHqo4$s5(p1vo55u%>THAmkg=hCNGX>ObO7oS0L&UU&>-#%+T zvuU7AW__RW$y`aj){Q)JdM#nA!WmC-Th-^D!)9rjVYvL{mHv0C^golc+=Tr{dO?nt zs(Ap_TzSG8X#v+ewiTu+o4CBR&y3}UC7VpjAzn_?bJHa^9)Bv`Ig6b8y*Hf0!0QmyuB zd3KY&OY{>=OE9p!)G7K~<%My}FP4}3^!f9G*{+Z|bB~!CP+#R-pVqdK?i@zfW}piY zL}YS?_L3?X&}OdBmzIF#8EpD^`o7KR_r-+=tqqmHyZa#y(k)^{3)UGBRFuKwMy^RCIW`Z(bM@$Y37YoYf%<+O%iGo#f z0c{v&FS%Y!TUx#da-m=iG;^+;StwaOU$Qz;(ju3%!1^`!rufjs6mU!h;)fSX0`nz- zM9CVtWKA6VUFO`MH~w85hp~715H>@B32jNm)!{dXzj5ZunYgEJ*&B-EIfk6I4Ko%P zh+^+``1U*tJmB?D*@0W)ykhxw(h4=+4r)pjiUOM&oallD zTkX89HesuiZFO*_EciOxM%&-0 zs=b`X%I$w-$hn)e(S*J!nFUloxKpOH*orQ@hyP!ynnS4?V(g_Vkyw>&hdMn8J#S#! zyhmv!>Sp6_Q;mFX(m<99Ikow3RGT8DHkpXMIhAUT+nQOW9+VHB7;4)CZpblw2~JWd zaxJQ!a;a7IAVl9|N%ujcdQXx z46|!w=O*o~^mdl?5bER~DY1(3RE4XadlCK=?SV55;hr z1{%7bc)m&u8bp{aEVcn4UGbaA@6P59GRlIX1`HPU(UDw$cWlEdQ0>tEo7QU_JZ;bnF8siLBC-<~TPqB95>QB;zY^I7Z(%eWnY7 zlq&h`^^8hGIM?L7KYD5mo2ZJT=SCEj(zBd)#U`sKLgCR7oC5?4SK6)> z_IIJ@=^VoF=;+zDK8fhbfJbV?kF<&$GBHRMKO2e-uy_L$Z{X}`czEc1s*r;D0pRBb zV_=+0DR19stXJ8+H6-q(&4M@-Vblm?XXn%QJR?!ktdkgrCPSVOb^<{WJ76%KGd~Sn zV(og1Zlz6 zK5uJJ*g9leN8Hwt#2dG4tA!EMf^FTrZC%2)Ubd}|+tz>Tn>U=7otIqGt|{y-4`W!t zz9Z=@UvRd~JF#`o%@?`w3R0~5&;U%=i0#XGWz{yrzs>K=gSw0W_koAN4lTk8=+R*; z1QxLD2={&s52qghQ1F?QORFfDQCQOtW>649X5%v&)&L_ac)*?Z$$JgEf8armLa;f*LC7FF0o82W$c!`)%hPKh>x2 zNdI0sVhD4R9k@;U3Q_;LQz3pbNoJn<>73BCSuD=vrpc`EsUTy81#J3Uqrs8$!=r61 zD1BZ@A9PU&I7>Te8to#7*$`15@@dM52Eq)0K(M*y#k|m>-l>|;m`J6RfF{!W$dr?F zOGP$I!=lUkR`-?tmqw>YVRg6CeSeW=1Qum0u`CrQSqg!J(O%1(seRaD3o5dp332G+ zRp*<|Z@8|wW?c90QY^tvQcHUSVilENZF{pVQB*G%)yJL7-!wCM0-n@?B1zMSu)5c3 zR~g>zbaiev-QFa?9YUCTnYd55NBr*397to+dW&tR^02ka(QnSqAg*TaI4`+Y`Aq<>Cl2CTDDPXf!mceX4gC1JSxhCcy z)`QWLppF$tp4niD4)E?*f;F5>3=8$5*^CYp?v)|KPg5j;A_!ve>tT=-#8)B3L&jI( z2e_N6|6%xd5Lc*6vq2}i$e;|MchT_N}o41PKyczy(}{ zg`_BPkwr?fEXy#221QCBNZ$rUsSU~$XCBtFc{xxh&uDbcy!XDp>TY%K1qgXdW=<{|)zx+D)~)rgf2;r3 z%~jf)hcs*Cb3VisC{R$RLBW-%N2vlo_;TGzKdb0xH3ff9Ki43@iE*{#v!wvq1AI`Q zI7!}y2S$z_gK>2b3@=dr7@ic?br`3zN69xQcEn>4peJj@dDUUM|5aM!aTEm&nu^-j zTP~5NOnAPc?$WB)S6^DqepJ?9+V=X6OFNh`Rd7RKQk5&_rD>ZZTdMPc(3c;P^J=Dp z{E+T!pf?lf{Yhs!uu~4~OsOA^36tiofb60Td>&mz1SF_asx|IBA`~~yB|0snqr$oo zTO)^iIS4Q9M21FGfs2)H8V2b3z`>-q6K3}~iUA}*QnkP_5T;xaPga>$hH&@W)Y-&;1iOd#CLJz+!MG!OPlMvko3{jh%K`a7>sIMxE5s_=AM~h5dx^! z8?UIAsM}44@#c4_?e(Z1CR#Zi&dRrICfN8BV^)re)<81LEN%+=QWcwlB~4GUOJ^jy z4N#H+NOOboPOy_f1Ra4qS%y=%dzG3*XRHC{1aOA)Z1^nEj9-}tjrFg?cXJ!^>4e)c zoVrvRQEi%&;_cr@EACXYR@j1J!*Ygx3GEG19R=s`2-EOEDuE%XMo0xgrY(LwFP0H| zj-4xh2PHtc?I|jV7!J}11&jgpmlR`juZ2ooLBUE2Iw)8}!8!^~P(EE#rJT|zxIjZQ zhnr^%e{-Iy6#Jw-Rdb%|6#Jw-)pMSj6#Jw-HFNdNXZCPj6hdN0l~htfCI6&7m89dc z3;N5J5I$*ug^EGMP5LlmkRzTXW(SLNoL<<}7X$F8P~IW|Z!|S^2(8pE1@giA0+N1d z)U%w4-n|gLljbrZol$%f(piFU9qFuAkWSKSuE|FF0STXkPgHgNCmT4r$?bA7q;q9# z&jSac``i-ms%TGFw96IkzYM}=fD{ZO2;+q6@NuH$zMMT@1m|pDr!v@Ok0qF&FoJz;Bj<3l z&D>oCVV3SL!j}Fubyp{?~b050n~Y&mKB(J@)QC%w`=DBFN0X&tL7pfaexjrx}w2IeEzKP@0k zh@gXxF4S9QrzOuV>hM04gZUYzGqK?na(D$)PIdHY+A|%W8czpS%7K-sz)Cx;!iYT0 zqA>f3NoO92P{5)`j9+@gog5c8Pn>K%2ZcAY@k>d0vyiLF%+7xY&jZm6$P)M8Kb943~R|<9Ba`L zmK{`P4+V=NESu;q1^yE(s%KM2Rf}H=$My@m0h_Oa!`|cZl57ag%tIJM-r(pa2Lwgj*~L#*46TR%AnjSPYMGWS1eT9~P)wEuHy6-W3@$jNyp_@TCgk z-+AW@tDp!8nAs2w+!~PwGm8fBLuo2lKSb&(SKI`MjmQOgm(Z2T2^o@zT(#TJQ9r7 zh>%(_<6-Pf&5Xytr&-#K7h(V7F3IM~>xh<{uW6szpRVbaYr2V{Q;DO*GgaxzF1fOc zGk8h~)P*MS$5-Jw6!KwSf{j=Q{}LdFHWr-X!S9CdjrTN z)?N8bTJ%!>cmkRWnD@ z;f->5V=AzbH*t=LB3&Qf!Ugf61ayP*&ckS|RlAB=5;Jh3bot0Mb&ll{*G*y^U50w{ zYgq;mhVX>ewYmT{@rY28UoF%4Exw!KYI;eSVEkH+hNMwnjFqFefs9&OF7un=4u#m7oc9 zoWq11#d-wbEaNz2RrZMje3?#cR^bb&X=i9{-==`b*R211=@R9)D(7B6%5M(HxCt zhjfxr0Wv8N|8J2o@jp=|MNcxXK+c2CYE2M!$`IU+mR;O0M^|wZ!0Bk09PL_g2lLj# zc;}_?Y}wjO*;;O2c)^QQXsVP~U&@!u)-3qxCp>=^UkuMiIx>+C%@;kX=8noGt7l8r zXG+$mOSkQkmNd?mtj?6IPM37bC7r2=&1b;`(mUyeS}s`(%!7RiHNYXXix8oE3)ak6thxq|IUDDo zG5RUFcoiAQSuR>SmO-WrJZaGWzzG`Zn?@YQ)ca4*rpB*8=v=RklxpZOCLB>jH&$!Px1`+zivJ-)4cPBZM%leR^(n4j5zYb*XuFu?A2aCA!y$q}Zldo)FNEyV&pH{**7ha)UB)am zfa9?BfYpU)r*Z*Sw=k%umz1O4Gk%M$0z4-UuyVlxn2WjIay{?T&HM=U)?ndsb`-JC z?BO3Fi;L_2t7di{AYi0JEgd#7sQ8ztKZAzS|3xs3nWBE2o?t>Kq8=F(R7rexPKk-0 zXbd&jMCXx`1p;g$?9&MxII&9vOjxy%;CdF!7sh4_+cSmj>B3cV;i^=~<^$Wv%rbM{ z>iH6~TQvt@R0A8JDY(hvFsLIH=~(di@+uTi)0BxcO~=!bc3C|t09Zj}Q68+!r~$!> z9o!WYw<1g+qJrSYx>U65c9aasGt=%B^c`{_dxu=Oa<;HDQ`ngXuM^ zd;#|`eK^rVgv>D067U~5$Tv$fCLUmP3j|2XV#|c0C!;i}cB4>5jfB*%=y3gk*-%p^ z)RYdj$f1^$`XR5jfW;Q&D}((OT9= zVVaohD+D-{VX%e4pd$oZj#4m*0+Pntap1?DSFFH@woIhW1R($%oO#81fSi*aC<5gb)4GK1 z$pV^Tb(v6In*3Zez(o0cVd<3fmDY=`6Z?&S%48I>A~!x{R1f}y5ipgy%jMf0f0ome z>%NiWM7ST=Ad`9QrcNR1oG~gu!D6vGq=S_3A2AE1|3tz6L%}<^0ZkAZd4nA7Ed6Bq z+K~uFfF-nA_?Xl5abc2Enp_1Rk^Exw%jN<}mi$T7k4ZR5+=H-Dw+j-N1ug;6U zv5ky2mlS&XerIVC)|mTD0^uY9$OTO5(M= zjtHCy!e&z3H{pcYC>L`i=rRg2b&^?}l5qUyK5rQ4^G^GH1a8zkcn!OtHBRqlm)VgV zSQT!2^)@p*fpTK9`1dm#ZQNS-Ih1KN`9ZS_7G|Ay?m^^huGbvrU7vQKqBKmF>%2?n za+&pdXm+Z$PdsM#I4-BbPy)Im2a80o92~vdc0XnZMVQ zqhm)$uwDn_*^{?WGr}&IGs?ndNHzmY(Hm zt{oqJme;jj&QHhI$gwr4z#2Zw$tTP&H_PooBY>v!P7Ri`m8wX*@KNo7in{|&aj~sk zDhK9{H}K1ThY+6>8SglOWY|CKMG3Z+NPX%%C1U$(zm{790etnJoSXcY{|{H2AJ#R< z))KL63FK#ehmV4(dYsb_1W7sIq{(I3;eU>9NS2skBBvtu(EPZJD(h6l=>Fonb$m4QU?#je6^5I%s2qVq@0LuYMKhqyT-wp`fjr`V%8|y|2(kaJ zdD4*$a%4j)vVj*!Io7Eqtjt7Ks?L&9k+uA@P=HFXnk?iaFMELREG~v?ahhNh?FH$; z_K4@G?QAAab|>ft1ufKb-^Zgm zxq$6)Rp*%lDNiT=q&=N;D>}~XO?f)_C++E&3rEk~yWnwqHNWiHFs{fEWPwAU28CsNFWnmbOJmQW|xPbG!f$O`0^Ot~1@ZzXOsbXNR zj8O$XMH=l_q|uRw_V4+)kyzFDegR#jWr3k`-gy-fD-bYC0qr@h_UECj7?hp-gqGOd z_=jGJ5PXRdl0QQ|rHAn|>pyt!Lx%<)dC;=V2#HIUn>&D+n#*SO~_ zYI)l8yhmrPUpRZWshh{`!JZ)icAEkw3#6G$#uJC0k(gXAteXDZbAafHgp^_F4$ z4|YYFbT1r)h>rqSK7@U)yn-0`TykamY~`9v<(g~d>B?@ovKwwu3msL+=`3C`U(=Q< zYlDIIg<9=lRsscNfF?!;Xp~YZ_5slSvKBmButg6bMw_izm#J8Htv_9{S+3B1iE2(o zwFsQGf~`}~tp{WaAA762xO={)^V(RdtovPjCsJiwuuO^JUeHb7xzr}NP#M-(wwA5Q zyd$W}iF+^-f8^@zcK=C5PrK_zGzZZe?M=NKy*DG2e6uh}@ygQPwceX+y%gW*q4aJ~ z?+*VhmlGkAj0vQP2CDx6!}i-=?PCV@2fH;bonp{{<{-Nkq2o%J^lZD{ru6i$9_1@>b`l=syUpr+Fua>i!Ss()KZP}b-I9e_}_sr4ZQ+%Ie zywb1Y7RP|>V1Z(Jn2Ey(7Gyp2cs7Trx)YagjOjs}Ef6!qeaT`AWFV2pD1n71e}TKy2W@%nnz=CC%sM-6*lYogv*yBGr%!sDh~i5`sG z9~JiHf&E_5v)Xl|F_+@2n|iywH={1ZZ9_JceFgqoQ3&7s z(A7^oNva*Bvwt|A_^?zs^DuHWG4|Ne(Xq!LA5zduwzg=NVUR~aib+1M(*hH?M6_ZzNwU_9p=j(Bi9_ZyBkd}99tNA*mX>QCsg@lf0`)@l4LKDpFA zVa&0+Cov<9YH(snFb?s;xOZ%w;a#S6aTqFRZ8`jCcCv|sgxE27wo(+-)$9AF18wOH|o2n2*Z^j zf0d-c=M35+I?7B|#GgTtoB#~;?K`-8VDHZT*#HFk#}Y@A!wj94*tWSC3Z2b4cwq0q z!2^Bw?>vNf-@btd_w2s+&_Sklk`0osGuuF=Cm51Wz!MJNUZCnt(RTbg1#G)@1Jp`? zfg4#rdV!js^&TD>g!A!jl!uV=Y>wUo*&vHkB60I;m%ZO=X}_d zvscV{Pr9&2F6>E#dfqjX2Spd2o@z+v*U0%b6Yh^fEffSH-=@G7ff|e}Tu?E$ev`bu ze|G)e%=*1^Wi@a4E{CuAt{45ND!pcBI<`xW?Sglv4X{axARX< z@wSRr%z$sBQx(vd`9r_ zAH|tZ3e%yL6ZcI8r#H`q%inlduI|W$J5u3}Yi&P%M&9v2X6*y1wGYgf)Wb?x@qNyp zJVM=bA0DM}uCW6=4E^W!-Nv8rz+PJTz5@ZNAr(U9GB5J-zL)k*wWS&#ersr^?ak54 zqd#_E-}A@$Kg$1U(O*@iH$9YYei%39ibv9+kISKtr`YFqxa1Ab)WO$-mx3wSLJ8C* zda*`s*1C3j-8bvE^tHNfRfQ10)!Nj*-ureQrN12xQoO9Rf3^4R)n1CP_aOZpuV-h_ z|4zt>kS#UoEll(e%leLwjBtw(gxJ6a;GP3y-9tohXoF@5&i{*N6yBCI5jG+uX0?3) zdY37ONn#D;1DlX~nURkt!5|oSVXHcN+G|9M0Js6*)l1yYr4no|8XHB;L*L^jqy<~R zDpRQjB*s)~%i^Wl6K7&uESt|$Mw=o!@`Ixz9`VhmePbm1RxW!)NPL%wa2Sa*18Suq zON)5)bUx`cB0*1S1f-CvAwc84!*HM|)*LEMggC|2x*HHD4cXD}EemmK)blgM$&c1S z9?dT>oLbd5*Tx@Pq5mHDGsMaNyk93hFMM$^#A#{L6E>KW{ zlEv6$`0j5^mM&r4w3RTQXq=6uZ`aI5MLjAjeF>SQHz?4VTpGJJ>nEyG-La)NDciRx zSemj8@cowdR<_{ze(UF=mPFQdIG*(%j&nSL@xBP}7WYrC!AG0tBAj5{`Y!F9d8m#m za{-0w3~piD+ZAV<;W2m&x*)8B4rouzkY6?A;ecc{m6b7zNo2s`NmnVrF2;3RU?uG-iW8a4?NyMl!=PP9G`jRJDL6q{K0^WXqVg3=qu?Q$^v@$* z7nd!#T;47^pJ@yNgZGzT_7wjD|Xlx>Tr(&?*S?fhFFB0&oQH6$37wuB^R_C1u zk+g*N964LbkCXEi->^R(jt4FJa)Edxo{RgzcmcB~k;C-l3bO@=`j`!f;jz6y?T2AO zY`+vIR6TECaENS+4J63H>n>fmDR5!YdnBae0yFb@Z6j)6)JfJ48yLA0;wC6=MaJ`( zV@4fWlZ$NR)A$gy1;Dr2hZVdXbaGR-jFn)gINJiSl4t1vL932*;h1tzHjhv$U5SkN zMck)5DcpOktM4TxJ#vJn+F@qPLy&4>IQbwgrG$5#R>X_QY4D`Pc(2K7 zn_BC7hZ$5{dX^rh)%9V7>`xjctwK#S9P}UXfP#Y>l-zOl1nKI<&Yoz$3HLE#jrKUA zIEh3|YD~kK%*xRlAVeGRsqbCZ2^NQL@K(ePjqm& z#qqW_aTmep7JVb|v{ICBV0jstU58zGhkJ3wbYNXtA9Jir^l)M98FGq^^NNPPQcpWB zhKDW2z_J$@ES4MAKQ&BM9VPlU;-)$SPDm|O^Mkelp!z)pq5@=*ML50BH7r!k&&oI8 zqY(3;pLC|LWt`#Qe5_r6dfY+@utU&{#RM$!VB!P$65N%>Dc5%?7DgKwLH#!NC3l{X6&e zJen<4AfZz5FzooVC0Bjj8@VJYs>AYjkY}uMj*_vxn8Nj%#S1#*KvCjwdRn0$Z?M_uvGm23QHNZnt zbXK9bnlLP%qpa%UINjZ<3R!WWX`vYJq1$dpeak|HV?_r!t!z$3n?IO|D$!M`sP<`w zlsFGPqXt0q@;ZR%8PoK;dW_?E)?8k-pIK)UYX+qWY5Gv;F;<#Qu4YFtIvZd%^q!Gx zJAc?EuiN>P&!hu;*f1q8+T`qp`G2qoWI=jq!R zytUCy@hwh@cT@cB98Z6~|Lp=NLaQnvaW7CgI1I+lYqQHiaRSP8f@vGTBHE?dB^_ov z5LOAl?3D!Z1ign{;tr(j2L@hGD?dz8>KnD)jz2Bv3A=CPI}u73(03B4Agbq-enbiHpp|VF zQ#q_}nc^Yq>a)~^pF)@Mz2?v9LFz#>{qzTPgMz=H4kYz4oqhra+q&}1zLaMr|D-)D z=kklr>?ZBPJz&0C!n;p|@rKJ4v91s@aY@sfNP)Vmnh$MP1{+)M-2wjRu60uj{S!e;j zj3Qn$mlpZ76&8o32+?#6ogw-ol(VbNm#rPJ)>)u-M50Dws0o`F_Vi4pwK$ES@d2Ms zka*5W&=_2GTS%BWJF7GjOuRKV+)+E4hN#&oq_V%HjxH>U$9aE1438qwea=Xc)eMdWKZ@O9ovtR#NfPa)*cris`<{VWvW?0lE{E97l+ zWt{_zdCPeL{N$7LuaPO)ZnJhclB}O}+B!0L?1}i`_A**aMBjaI#xdP^dBtq~mQ4MY z>+9w2z3KXWa{azDoceAnG!PPO@lq`$g5n?~hR2>50hUj?`i%X>n9huvVCSA#)z46V z{m=)~vtj^%SQCQI<=d3=-%;=*+8;EX%TE(Mz?p3HUL(I*1(WbpNMu5YTJ<4OJFc+*e%*cJS(Y8#qZKhFP(S7}6Kl>la(25gdDsY_mK14W9yf_AIuU9Vu zTm?@&fcXPc25gS9$-X!eXpnpuW+GvMbu<%+)>p7V1??lWt9+Sm0cq1=d;C&7HdaA1 zf=cLYvc?7)7!LO~p@KS-Z9m8GeoBjvusVk8S$W}S>6VVc=~x}1AqHOfUs5>~c&Quc zrjE-kxIA>yTns`*#K{(e6)s|Vi$UNnCr303hP*OVg(19MyOa&sd1n`r4ES1sW}}du z5&sVE>Kh$6;q1IPPLM~L^I|_viO>mgaKM4Lm1Kht^(!22ZkA9xDBQ2uMAgg_@&o^y zs9H)@Sk)+w|9={m38njJ^!8EkAOgY6D?34yEY#Yo;b!d^=sVlc4ERs-IVu}L1-473*w8MW9lah+lRiNYF<}q0rDUua z?r=DC1`#W5ZeKZZh9&A5ljG;1467{Tx&7gleuk@eb#Rf58-$w;_>M&b3mJO2iqZ0%0QwAVTc zn6x3T^_j_1iHIqpbG5anGdvQHAzj0>m!rUu=oL!xt8ceAP$dpHV-@SQ(4Qr8$#RL$ zimhRc9la!tu2_!Gyd`M@!r+t(?0$IbL2EVq9k{eXIKXge1MY1!TDUj{%?|rt3G)Lx zXE4~(Z3_0&%&nk6pTkx3lbF2Rf%T^;Hb{YpNLp4kJEBvd&u~SlZyV-V;(okLnc~V} zoBSXY!4NEmM+_jR*?@E9ZM=5q4+ds89LQ`qklyeydBevr^Yb?1)Td%VPB09&Y^!=? z?`jjBrFmX1T{By{DO0*BUAjds-Lg=mR+ZJ41@BSK-={!N``{N*N0bid}HudgQu#6CrZNLMf~~hTmC}^>-y2F!lVPmI2k3U63wnT2KxLlP;2?47--Y znZ)x38Qxi^ix!zyf-ch=cYeh|GCg}47s39!Ewd0m;b~fC)!LHM7m~i}wxAubunYa7 zvE$O;VORw5Go7DF=Id*V^6jUE_3JpxF1_{j5_^i6fo;ggbXrto3m3DJ5YavR2=taM~`T&=o%_l zf@Tesvvgm_#ea_eHz=%_P;;4HN5KjjtIy+6BWms^)LaY-?`8zbO(vYgASX=bqQsy+ z=ta*i5^&Utsx^cfX_vCESmXae-v!H#;%S!+8w8A{x5}gOIhkv zGi5=`Fm^>n~8wmo^BUsL!{M$ozVUxN>E?+xaz9mz>C0)K%F5f!ooAhxz z&?*MYaM@*`u^~saVyf=qW-`~x8_QbE0+s*|bRt~h)cF&?)dl`f3-L9gz4nqMvpnlpLWiZ> zw6g3`+ESaPM7Zr4T1Q@S9bxhW=qNUV<*cKRj@zzU0=HG}-R8E}n=_H->9KTVr5stA zVjse9dEHnA3BSd;Y9URpzA2{Qw}!_}85I0B)Z6I3+34wQ_1|oFBHS4H@+ga#IJ zKoR)|6_LLmxMmI)>8osDuEfewc~ZZ&=X*V`!2#nzDsj_0Eu0U)eLoK7r z9y*vM&M>F$T54l6DhYvyRKqOGXuK}|CLWqsx45Y@*=|J7kFu&@=f)1)XfxkIDwHzdl2US(iQy3xe+j)SMgc z(rw95Psea^u_oWcNnj&Rl@4VO|1zzMof_=(_Nx#|lT5vx)_44ZogM%vea;I@USb z%V8mXg!O7VwE0_DucM2vSH?-Uu2t=job+?rV3=|Ovvy}=>qT9rnynYEejqMW#_}q) zS*C;^e3RB_@2|8*u|I{N5Xb_o(MnpQm2=T{QrvBnp>J>qng;m5j7xFl0v4!}mmZ+C zSxIZtkj6^-M_r(mv_LI20*l$EqIz0FS)eWMKMD7gx^4uWy)Et=rA@sJ-Wyw86yF|1 z{HDLOx5j(3#!K-A57KY8czWCYH#?jN_k(C+ybaoERaP3s4XiY;nUzL>n3?Y}qbPq* zGl+r<80I^qx?*ITh3O=h7}SToX!jxkM=hwhUjel+@OUg62XEuz%!Gf&F^H=YcYN0U zu;VrN7nwf`Sg-pn;uz8bM&AmvH2gw(m1Z1+S&JFkkm$&ho&Tr?orJN>3>BsL!EYF) zVD{;X)0G?L%8jahy8nGq3h54w7TY|SegJ-H7do1A@Rqgcegi1M-4S~;`h7Rz`kyqS zumoa%S44q!_@xmA=@-^T$MAyKQj3ldgqyVDcKs$0gfe!g|CY(0%;zY=~L!SMp~=%%-{eD{sK~(|%Jo9T5n{U64(=aWue#Z#p92 z#kY3oS~)U6N3Y?k1gd7a;3q_+od70ma~F6AZlvNL$Ab`oTXBTyHH`^py~a)U&lGiI zshH;fUm!4^cPYj1WFG4V2$4pIPYn$GEp_K#QfAhjwmMP93L&R@J*CCJgCw1gZ#~v3N=K#bd7=zjz!vX}J^l zV|5n#53_;yA2$jOfQbZt+4rAVb%kC31v~+y(~X8pe~-AOqLi2n@`^%t`v0Ulk{S)p zGr-?@F4>(=2g;!#no>W!d)??V`}(fO)63C?6YHyXu2NSzXke);B_>0>uH2pGf2QgZ zR|VCDQrKr_!*!W(T{_$#hZ|CX2K!z;N3-%@;vrRZHI2CS66+_`jnRlG*GH#|Y5HIc zF%JBi_NX!AxA;yG8`LMDS7P0xbAZ_J{(BT;=`u=8=I|~fXB~e>9X5hQMe>pxe!2Ul z?(^F&Y=gW!*t8suG53~t8#)o~vxW7U!uoV!qg>dS3N8BKGlu4cFk?uwjV;LihyX%p zix5YiwSI!Z9mBa5z5m3c3F0qxE_oz+C$s6sRshWSQy;*=skxtUs(1`G@)Bc5hZ4z% zvKq7$$eL7F^z-4GHxkq9FL%og8`HI$k8u{4gJ*V`d2`7rVy1YRoKv z#>PeMW0wv$Jh0zk>>jvkKYj|fPzGR;@M(#TI!OUMhRON@#Vw6Fi_~PE(ipy{eL$12 z4(R~E)osj3$K0Cr%>Vj)|DGGW-`9zVHy#oE z4hqmW>+c|sZn)qyxpdWF?3pBfX}y(57>R}D90e93F>{Hgm5q`$^|(ZT&>@ulk#%QB z8$=@-kSmlh8AUD{Yq`W8a5{9O7Rr93*V6ek>q99#rfUFLT)2sb?w-<4zlraGj0Gn1 z4!fAVL+jP)d`tC^FmAH`&CGzf#Qq%JWoh$frrWERt(}-NzQbC!am>e^Cmm80egi&Y z&lzWmy+ID^d#Sgtxb`R8dd6Us^u*Y3JT`Vbra+EY;xSr5z?;{g zEgY3xpcqXesQ~MbEkbt04Hhhp3=chh;yCOb4jer^Fa(pM!!Uvvmm-w!1waCc`X~z< zsUyQM+{4}I5<(;~V{Pk^1AIodoPS6e-EaZOcmg7i2F6S|#7uHnrTqGzw7SX91jiQU z!$n`)eR1zwE8pz6+>s7<%Hhrl4?8wqnaXXL>A$)UUkruVlqrNQwJmbtmQ={*Ggk}S z;BdIXyjIIa*j>D29MnUOa9d|9`Z5)L>583l#m-dJ{sTJ}c*sRYEYtu8(_Y*A>fTrO zU)(>re-36RytqShmw+R$XkyoGI^AA5HI~V3V3n*%)!vsbyk9Q7KNY(FUHBH;pKe?) zH?E&>1Cg9OIPn}>1_U^7Hc*ubR81X92kPZOeJTJWoBm)S?7mIx5&z)t6})n95O(9# zfQ};Un+?S>q1bdZ9cq?C&8bi`^TAU)y*?Fg!3PT2uZ3O>y^?=1e=`4es9+%%PgAw? z9l<=C*P{mbBxnuaXsYe?I&OMny-n_0U4gzGj$1o=+&f*OA6c3om@Ljae}ae!%hI4K zjP+>oUlPJbjOzyWsmbtz27Rp12x~KJJR59283RaUfG202QV|+~(_c$3nk#6dL`1E+ zhtZ@rZphhuWoi$M9w%HdS;V$8F|ii%;KU<%5`@}vro1|xxitl4qG6WVOtkzmIFht( zh1B_MkfMl)#8cdH(y1b}P7WVT>U>$>2${8sCv#a__>UFTh6rneGU3Kj;r3LZ-THDG zCHC^$mX{mxaB&Y%Y-)>k;7xYQnDRMF<`)d4ZX(o{Oht{mmP7v}YDMRxcuLz5)Kcl& z>IsZfzZW($d`Zhnvk

~BX*k&(!dWKMJ^+Jkci|;hS@^WNy5!EYJI3PMs4#pdGnrB^x)SH zO!s5INJlrw(G98ShM$g21hEB7#lQ9R*Pnj<*rj7LkHTiH{B<1x-T8RUk=}& z3f#}uA9-9BX%j}kSW~}(molv-fsCYqvwC0F$;eV_aXAI7?KBNp!_2hgZYrIE_i3a5 z3q;One{-wgl2fE4O+S5(H5*9FelN3jvP75@BZ5>6`kg^*-={`+_6Q7B!%kLawUgCj~Bvm9Da<4FtGG>5dqOUib_*YdA}|9Zv4>DvZ+ zGkZNF4yiYFjUh(s791QtHhAL5acNj3cz4j^;XJxu2dwIK&Q>et;qp1Uso$6+0SKVzSWK zt(^3}m->|!FU)12V}tqU{TKYRfwD}XY^wTN8=!nTuvHFhO$D~jl{65ed9H%K!YZLY zzhTP{9{Gbu1OnY^(tv7njz(h*`cCDT>d+q^Vc43I&H-kl_WVkW8!e$O2mXr`;W$=? z;T^6d{BR7p2Grt-C#bAs^a0V_+ONg*1jTtHzKzk`+Bs5Y0G!j@=wa(6mSm>6jV8ku zwNgX839YZ}PsQ4aKgXS7y=ex5au#b2bsu*ARxjU{{3E1y{uk< zKBPxAlc{qdptUH`lH>Lu^Q0Dn9}IkfR6FfjT)reijy70b6o(Vh<-seMFFIfy3x)=OU=d=MTs`t!z zcVg|Lw!BR8SjLgl-eGTzzzS6qN^B2<=o(ClyOP)n0nzmoqRrgw^miVPs)P;}cchNWwRW!m(BF>l8jw}Lp&j>ODm{4AEipKU;l)}e$ zM=G~@X8qOf>y1BJooU~bYTv`$0O+o9ZWonaguqOt%qIFQRGAGmX1D50G+Hok8Iy>* z4DE8>A?jY7L@GJtVl5!4hm)uxZR>r`x-o%E%{3b#XlSTTQ zG&JZ%>ggQT)9_Y(;d7}#4ad~?AWZ-RG}~D-`w2Q}E?n(u^SX;oQVrboxxH`l5 z!CqK8=Q~u_APr6q0zj{Glt3+jdny7E2B!da^m^UiIAIwAQGges6_x`sV*H|gZY>)GKOZ@htfE{HcWxu!qf#E8eha4_C%LpmKbgqZ*9Kuh}uaU}KV*mHZ29wTADN{7CRNv-P#X|ysbrpsJEjUOVc5wU&He`q_u zj65z&E^05ktbA~;MC4_%eo%-{9G9fyr${G(@OX%1i7h?wnUlld08j(5=wHAM78e?O z7OBZHYhyWe_%&L>Eyw~Mc4Nz%J1_4f(rEn-6+#MDb`>{_IJl*SsBt(=^K zc?Cs?GB)W8)W&kVHa<)0VQ)|qNv^}2xDbK>=;hE$q4W6{@+a6IYmYEIDDm#Nz*@{A z%Qi<-D_Lc(jBydaMfD-t@r(mowamP_@gAkUL|8x6i73x`=Pd4s>t`vCvWW)c8q)Ds zGZqQwY(cz1xomJ>@a~>wcOg@v8Y@@aBzuNTNt0+pGEG!C+Q={R!x=X_H6uB{y#_=vZa5cSElnyt^VMvIb!QIa9$FDwhy*S;m zL+*gcgi_`UD^pcF(}la_!dC8xG3WR(wT6=c94@}qH{-b)PB(6n8=(!jDHYgc1=L!r z?p0bfjc@B^Y@rAN#9=aSIIe7^%BeU$I`G8sk-?F}1IG_50&cEW@*-Yk+-^xWl&rC| zl$pqI|Lwm=7jrC<28U0+`iI<8?>6cAZ?i?%J5VaZjdpPpXzNMHuJnLU=Y%nF&-* z-J1?H$$_Sn`mtXJ=Ll0cgo-SUVi_mJQftA8X{zhqm5tius zRAL#VHG*ZWVS?jMBCjFqa4iRe5_@iR1!^I-rJC_KwbJdi24O(SA?leLTZYXJiUsZiHKnJ2GgzNB%sWJjiCN4lg(F6l`{7X3gb0qMUhuS5?7 znZ#VA7>a&*C6GdV@QX@E1PXz{;0isMk5*pX_sW5b2Y`FEbugvFDO9Ez%7%F*b0w9p zJ@x8SuZ&zANvXbBO%eO|L*GUbpnQA=3ODQJ$of=dy`e6obXaiVz-*{C6RMpKq(g0T zs4ZpqEEJ)dBsy7-A^F|no^6gluI;IC+^C54Y;oV%*3utv-)ySrbGUBqa3X%o(bCrf zYxLEKzwM_K0oD7BVi!?`NiOUu_K=jZ*Da7#dHz3}@QJ!ipiWUG4Rp$Z&XoGGLQbuH z#MOU|%Qw+){IZ9e)|EC|gEg-q1q^-_0P>(#>Sabfj5dRf2!(XWNM+)VT7ZcIjXOT| zmO`IyHkM;AS&h4{n&{TJ$3QWX?wkQ~spXsHIviP1slqnz{^UJoq-C^4*LWl8%H8ml zUD7s!BtOP0afXGVE=K@g z8!S@{eAj0}_0yZup_OuIWr}?u@PwwEJ6NU%47Yhu$88|EA#hQ);6^qqKQLJoG{+Sz zd&@oDfB8ThH0ar62>WOoK7MJY?`9lL=zk>6P_GnLNA zoDoxOq+djpjZ_5_omiN7x&Y2L7z?ZCLj{wK7gvKAmP7UPp)gZv zOo!^^P~Ce$Zv-Cn5RhVZ4g(IPK1cPEh!f3aB7GChS-{n@5gQ7vf2>`nRo4OY64T! zW4k=zp%U%Ne3z#cVym^+M@^#OW$MotQQR5B-&|!Cc_pjjpR}iH!DFMv=W~18uuOy? z$4S=6#K7nCVoixbL=mgN6NZ!AVIVMwRq9FXQYd@N;BK4*MQT7<%C+Pgr3}M~Gea4T zn&@UT70(01{mmr0G2G&rd_g+nCI-+bB&LrL_=>zhC&XZd)63Kyje##0jerQt7*zPY zn1_o5Y;LlV$(9bphYt^)92pxJJHn21k8oi`vQ#dh6fHFeR6bgLo-h|nXK26>FoO5Zds`7z=7 zWmL1Wx z^XZn2a?3{K3(a?QUKzeROt-32?87J9Efgj-QE-j|Ccn|T9x13FAHd6qh}^X0;!Vb_ zXPU~hT;c#Es)Q%BAvQi{)!0`t6;(R+DZGiFVPeDZ6Fki|?iF#^EhHFw9^)Gy9---N z)BVbw2zCEMc#v_l(8;p_LPDpT(}6ZQ0FB8uIz&D`8;)hdv2?gz4ij_>t{{wK?`)_c z6Ka_5H{tS7h$4Ce0Y_UgXSBWdbkfcGnOGiy51FtIU#)2}AjWmJh zljYV`p$PYiXp1wYm z4)w~R-c+cU;ShD)%jh(cSID6iDfR(_R(ydu_}KAhhD{x-_@(BR{t~LeC6;kiOH&V4$aqp)vYGM& z!%V1HMP0iYS%5sl_Hdb8)Jl_;wz=S1tydY1elQ*CltY~<_MvIbGg+rKwVm}3&2Q=- z1<3N#1tz308ypy5XYL0E>}G&+tBI;fz#S`78!`b;rqytc2Ib!(^6Oxp8G%%y$%s?y zoMRENVZYK=6rR@NB5TQ5uKl_bOI3F$zrm>?1AeBB=+o!{iztRVcXaq!NRMqhm)~lo z&P|}(4D6ehOnyr`zfI03sAv7KBV+J9>k8J+SJq$Jo~~?{E88dfFYG0I!JxNltRF56 znGLsP!fokryR4r!BclkkQ%a8^0BU^;bun#PDr)^GWqX*iDY{Oyw^=PFoTU;N@R^_( ztpVu>JxW4k^C=frCItcN2x6n1(f&YDdLg(IgM7CaAYBY{yxu6~GY0v7LK?-O&`DXu z07x{BwJZ|weVnQ{gqmp=e$(Z=(~3|ysNz@LkA|RS6kxhV9(It#3uG@S)!;#iPCZJ0 zia0nVkFR+&NzS zd+N*Krp74Y7w_4h`4c7iBDBS64yQeDMJ##TBa*+1`It5Hk^l%aQ4&FQ5(zaA0nMj# z-|E@37}?>C4aSC!A3HHJtlohD{XMi=`mYoWVjLt=v(t}`NMunr8+dYfY+!Wo*l^Z= zYIyKzY4~u~jX=79o6s42fgWaKyqX?n#k@&rKfup~4>2%##q%R&rjv0RO1hEO1fh*k z^_wrQn=Nk26gN%B)5Yy_ar;EhTyAkHw|cIuiVi#9E~}TzR^mHc^z!MKPM`nWh0o!X zbhs!LuBA`io^-fYX7Twzo_-qTjl!w^*UK)IO>drw|NgP>9lLV;>hbGi=|I06=uZXu z=ZmW@K8Ewr#m#bYGjQFU3H5TyfVyhfxa!cTqOKj1mGJ+>88wsnYnwasa;a&V2PPII)5;uwLd_hZeY` z2v(g&-XO&-`QgJ@n~l%|K?|Wrz3UKW8ci3ej{>H&(N8gbSNSWv(l8nSfqrg5769lM zD6UU1x+Ur|Wy_8XCI(Kxf*g*^s%8mbKVF=k?H~ z5Du9L+lO zy5~w8;LHq8?r(>q6DQd$#7?BaQ+^85XJ-Ad?dUU@Hun*;R{Nl=z*|fv;_njh^+N9$Lh;%~O9hwn&NxC*M|BuFs#}p7cgLZr8uwmu$JfR4 zndP1J?0BO$z99}RQg|5cikC6A!bYYa8i;RV`k}%2=6D^_bK+a#ZTQZOcgI)ZI~3m< zUybj)__p|3eCNmAn3CJGIfsT5W8i+k;7qc2AFy8OxdTr;H9RzS5Yy=37{KST$2dQt zhctsoC*!f6(dQo5t={cAId)RwiOlvLSuh+(uqXHL!cpv#XihfgWMX*WkK;6A_^~JC_E8*m{Zi>~RvH=*q${pBbQXRfOCtJxg6Ufp`VuC$$?#|z%HFw`UvzbO*phnimM z=~)-=DTamH=)F?9X|8eN^f5qBAJ3UeoDeRU>KJ#}Qpf33t$%SfVe6DAT(0@fH3 zq<-{?qz<;y1R7_{;8CJbf5OfPzMP`^m*6g=T8VMgmS{`5dY# zO;haOVAT$x!rG;c#@k3TF^OFE<6)Ll8l{>d=#lC%y4u^OsrM`wG)oOmp+roYOA!}4 zAvSKZxUVTlNq>pA08wRV2Sasdk-#7pGpI6aGPg8liV_W-elK4h$fDLE{SQ~ zmxvu7Vm49YP!Z;aW{*h6M~|OO#D)e(MxKC|uLK5%b{(##7Dsb|8@+%p=?MfzjvwS7 z(%?~S#LQr=4j>cBdgIvH=Q&FQcnl>%@toO60ga6_uI;Pk_U`Ksrb4X~_f2`^vex-< z;p7$~LZ)H#vmq63m@A1*7hF7+iZsj>Ky%HVS2$nNIv3sh)2AQ-E-i$1TWKM%zJfxW zVWMNP6abOsPpa|tQa-vRq$36Dj zpSVRPijj||uH_o{nt{QEZBU`mhz+Jf(RSLm%=d)h2E?PwcE)|W@;!NyJ&QJ-_C4=A zyG36UPAgJ zAdy58I^9?iGZiP@K*OcKq2K}qa}+Q*O&}U7scb!;qX$_LZ_@n~f~-$s)0;aXAzm$j zGF=QX(}F)aIzV+ufF&6pIDGV3Le|X--ZsydX~C0^U;X3@RLV9OKeyp|#8E&jX#`V; z^o#=gOLZ-w`Fe0^2EOCH4D4D=NFuB<@p2HY8z2X9n2_Bw+%oq34g%BH{UJ^Q zjIg5tk3Fz5rqiT4G-u1`L*D}(gVK`;>2)Wb2|Up8^eOi9cTt4EekDZjWrFs9hK#D} zvyOTv&Kc$DMwD*MhbNWG$db~P!i+Fkhp>kY$bz2Nj6Bl*0aQejtdn@lo*^af8;d|% zhrKc`SgmOF@8O?c;x8jAgk1vU#!>8Mmz`g6Vi#LpZ4Af0)OVOw;;@ex4t!0A^n7}3 z+&k_A{1@tqJ=ka5SwS=W89EIou%9C^*@LI0hbR`I*eVKiE*k^EjI5v@md;bYzeOyY z%eWWZ3ZV*iY1(nvOp{4sQ20$sBLK|gV;tlvFgFU$+sFuX3ye&FWUUdyvdJ(*&{jr) z8ngxTEDSAMUod}u&HeL{;;$Wj%YAY5ttT&!rb?jOy5W7dt26(0e)v7FtFr)DR3}a? zts-68>Z#|UsZ-bV-Mnw-y&1k7o{e>9V%<>CosF!_L{`pxDjnG>N45g{s-v?7b@}We zaOEP=iLuE;sc_@e!wB#JAGv+??{E9wwktcX?wD=AHvBL zX?kqt;px$IV1vxIhq>a)iE;fe6{zG`Tu9k{1`eMb9r|#kwvM6Sf|X1*;&u;%4K)ZK z@{g&@88^Uedi=w}Jvea6m{01R#|3(g7Gnb~<9f^izKm(g#%apB*p!7WscB@gUZw?v zA+}z47UfzmaCtFx_+>^O#OcZwuq{F-z8}-t15ZOv=V1w{jMZ^jy(((-lTDLGHsxYZs&g);OwU;S zXq?%dOpJk9c>;}w=?DfZeg|>sWej-M3#-1Pap^3=V7M`zr>Y7HolibMq+({ z&Cj*BJf=y^X0Iw%(&nc$fu@+mO1U)El*yVbF>GXp^bF0s2hjoG8s<0(OJ1vfwfdFX zi?y=_>oNuF=0Z)h$uv!mq(a;9xptU;V=ffZ94pM3@Y&6=xp1*!qaKz)LB;T`qea|0 z?1qZ%8o~~tjnao~lt7sO3eau2bo@Ji(Z)M{iF+BK+U4=1hG%o(u@&$Ocf zlJpxr)S@MZH>htiBU+r8<#WMro(m!;P?#E*RM2JP=rS9iDL^A5uwvE3d72b&p+cAx zK5wwi20*ltQhD1@jpbXFqp9FCq&aUfn{9#T{qx*)VqNmndgySZl z&*V6wyh>G&A^s@Sn34V*&w%M_!*JH6T+%y~$-`00&(ovl=uIR5!>bwo`4Xiv2Emso z#xT(fTF&3)FJY_r741H8wRuUeA`O+`tK8rH*D^+nuN^)R;E^emTEdd0h2Va zjgt7md~;-&HEo&F6b0X);9C^XzRFqg62(}5QSb;&8B*0hWB8l%97?fI+H(ldrKWza zGB&rPZy`6|+qK|WEQq;D=|>E5e59c+1`#JodBp(AL115qK_o~PCxbh>NEzbfbL185JIJW( z^?bsE^v{#S7E`(x>0f}j*_`e}`WMMCk}1C*=`Y&Y(hab5t8t_tONW(RQ#mL$3 zFGPAX-rs`ve;ERG^ZSc%|10q|mgl0w?jW%uUye`4H+F9>yDjOJRNMIP#9xc=x74)?&rHQ1v^-Od z^w;ALTheP-`XiR~TBLtH{^si(m4@FU5~pdcU64`;GWF;8O5 zoaId9fikQYR9s99cP3P@&+E11^^g0{)IqplpWhevi_Cl}7mAsV5!dO!ctEGxPy3BJ zj^n;@|J9)Q+y=+#;CRp;O9LKgTGJw)KIF0&LXd^vPN3PRT+g~6b({jV|ER->Kc;Mw zyWcP*#$Kc0`6>-b2u=Q)OVPJBG~eh9PnS;_wW!6R5gU4%P-2hqg=*Y*4(Pmz4<|O* zM8aDnDnG_QfupmBpV?8 z5YpO|(91ABN&zW*LTdU$d~uwL))nokj@X$qTyo++B@Lc90i~!0PS79d#XAEhtuItNtr{I>RX2IjmYniLAn>sYTe(JGQX{-4Y zX?-^e4>qZ2Gd>@DZ7+{Tnp5g0LA=x(O*uWA9XB@T^t!n!mZE-z#_r;F1DQ^fqSsAO z0C-|GzPK_hX(>sXnv?WBx}U?X&YRex-=>_Tjlxl7O~(lmDy9p??2E=e{plFLxZ(hn zmn^jQ@c&I6N{XZ(d;ooch$AOFF?PQ40{q+ug22@l32+uMr&!Gtbrh7nmiub%)b8m+ z>BtH>vSPwJS6cJhXJ7s7^!97()1{l_(oGYgx!lrJZte8$@819I`>%zr52qX9KcXK= zR>i8kqN%2tkyKuHIt;mA^=Iaa%3s^^>XxY|r=EQM=%u6SqEWz$5y7_z2UHe; zlb^yfxpmFvDPCE)F{WgdX}pBH0f>4Nv~HSL}++3+_x#mGk*U1Z@Xcibpxi2G1+c0t!1FR8IB0a^&I>GGTB0n=7c63m}ho=WT)YmPzmJ+IG2i^JHit&!LpUiZTUk zyZfEOHpi8mjqX2mZWN8NQ0KGh^F>6g(1_FU|oEJ|_s}?*gREx_IWHP{6J9FHjD;l`W1RAa2x!WBr_rnz}SGGCX`@ z4fWm%z4rj6cAg)(FrrC2tPuvTc1aN$Oqj26NNjPsDMo{;0WunB0wAc2^G+io;;u|G zcC(8d5Pz=yyyU%jfMj0c0?!ulLr%(pkAcL{@e{+zdQ;16@~o$JmZD6cSP=eJPTzYC za^J1#@K!lY{%P!CFsnKl?iH&p!e2Vqb0%bjygIaHFj<3zWbw5eb>No{T>+D;0F!B# zQ7&-K!&s8kh03LuIpliO0IBWsfa~s(x{VS>oJcdkU=uM!_Xq&9OUkz|GndZX6(A?N zQpxEY4dS;}Z#tWIty`DE z32G`-RBZV0VI1MWxqBSHAB>McjAex$+|%BGHR~3d7qkfgg^R|>b!RG6KLMP$eI6bb zHccF$J)mllJpi0fXOIUwK%;iH-D-hf=Us^G>Y5J3L)0T8; zw_MsiaWC5-aM06-4WcS`>E5Z$lL71k;+~-G2nB3MKtT&pN2F{boCu@d-z@BO{Gg;K z$9*H{MEGIe;1fd~bOLZUWO^sG#Yh82vx&{<<)g^Y(zuxL%4~tMzL@*EC+RgwuF|ka zBOEO`K1TgaG#a7GW#>P8;j;iNY|(ufq#84a=f6^IrGAudscT572{Y?!MTXgl$pLor zA*vzi@K6n-=TBWYHIdIM$XuL#7@%5`Q$DSd=o;!y-lg@3h(Kc83FwAA`Yy|%TP~iF zb|JfzkC+imXLFUxlHbQnAY&|MtEGIF92?Z)RUuU>Dd0 zuy{X7fFuBdAPG=>i!bmYK15O^Wu7eaAd&z@QY1hRK#O8P1-5)=NXN1v9aV;6=>o@6 znJUW(eWk0TZCy-CvVB%1xfx_+Y;6t+Di`}=UvgQTAxGxjIr+Yx_wGWXWxFb=y20@0 zY&~1h7 z4{l?Bl*%(}a;G{+V>Avo?uRE>54RIFG04Mb(BlSqcz5z)FYV#oZRFM&@~)Iuf^O;X zUA++B|Qae2}`XWUs>#=9rj11OoRe%ZQc;^fO$D9v0I(op*XyyT?xC- zVb6%m9}W(l9;&f&2IZ0uesRz{|F0Ab7vw&3-J2UUGeYy6V_x8$gGiY_!C8`Z4HulX zTVrUE6MfeHes7tXCXmohcy2g2k#OF0p1g13tE35v$Fr`Cbdlkpa(WoB*YC9PSz2R> zi(bHo$Xzk7vm`&o^_YN)+`k(&sx$*V|7DaE9gd#0iAZv#cKc+tX>`JlbKc0- znHUbD!r{V+S|`?d8d~o>pCxf2E{6w@Db1j!&LAWjXB(`vBmUvMD@E|= z;0n7^gg$SyQcNtcp4|Tr7YfV3@Nm(oEK`x;up3{^C!NS0{uHEfRIKeG~Z!wJHPC0<(Q1BC#f5V8|1dm{O zRNg}@^!E%8LRgpjghKEM$PW|_Q^7=sx3~T?r%s(2NZB;|aqjN1gq~22D^K*C{M2zp zaCeliGvn_7w8kq|^j?NQq>4&CqKeRLHeWGXGmA+%Z_3BG;J=Id8hnX#T#A)^q5qkF zt*9O+HsI8;>^mLK%U?EK(=}DIX0m3DR-Az-IW8(} zzS%cj)%arl*TZ_%O0B9(uj(2LP1m+*we5Os`&d3)9;Btp;*RM$C`a8mdh?uCw^y&* zJGL{KsQ%)<=k{@1Hnu;RsQKdF=k`v7w8RoUu|!QQNha#163ZtO%V8(;V&v-&>&v!i z%eLvuwx#`2*@{`oS5^*vyD})9*dQ#`w@uY8o2*-=)h*ZSmc#NUEY;LcRkux6w`tYw zdUg9)cd{DhHIcH8863aSe*Kd#FV`1t)M__Q*SG2QYyZwK*U|AKKuD@vIMaI1RO`Ky zt@moJoAuVs<3-8J#d_t6smdLbl{=EPZF=o;D0o#>qas!4GlGy*wPdPt>15?nt#X-O zxlFBGmadR$AnQSy?^WaJg^m|H#`2Q!3JP^z+J!?u^xAE=wrla-dVIGU-<>Qa$FO+K z^`PFeL2clHVeZw79jx^+%%!BLw>^!O1q zek57fG&bz~rT5C{B+*k2m}SS!5g1|q?9QL%fSCL6QQ;amK07}SCs zfjt%Z?^O8tTrKmtMm%>G?Ae(2&Sn|V-cuq|M;T!pKd@zCn0dK;K7i@}=?!rF!aa(( zlt#DgyVv8+D3giU>-$pRr3@Z0jd>jxGbYY@YRU3lxk+pTZ6;?cOZ@`HN$K{b95&Q-1oe=8N@ z08CiM0i}%YNXMjD0$I6lu|b3XVV;6v$ zI}hl)qT9Y^cOCXc%*(tosICxbXRIRGmwQ*_bez*+y&-QYG8jO^0k^7w!}Ie}j92pJ zEwjX_hqK!l&db^vK<^~?`32su!$1n}HDr~pq4I3FW9d0 zHLx=)+;hTPw6}4t_}r>7^ort*cQa>)eH&3jSaOA|#>l<7%XUs6^gn`62Qu|PJbAe` zyH@@vEn~LIf~*{Jbq83+o$v(X+Tb{+H|DmKb8r7LRj|DSf^O(D6|tMVEpV5$wgimI z0dyto*H+*Y4O_J|pO}lIwxTp4kwKKU@`;lqRd8~k-=uU?d8dRwo$Ep z=^0XvpX?(MdiqRnUr&!AEetb@zhnWw0I;2uSxPWb!OpZaVb*8hAd-0o(MqRkrb}f< zH^%+$w~3$rCyFo?WRi`|IA044;%qe;Ll>q@Td+o7u*TGd!2w-#^;$a_tsOsNxFZKk z8eRemmwvE@3<#NGvF?j=wM{(`HQt8%{rB>ugusmZpqMKcT5!6&Q7>u>IMT=10CkF~!vtT&j)LnH0VwSQXk$2HT@QXEZi{m~mkAVE86d(v4j zDue!v7k}Z>GnbyeeDyL8lN0M(?u9LdnsZ_MT*%8h%~FUAVA%^nCDNZmB{JZaEPHYA zGa>iF=Vr8JFOkE+3HRcQni*H7U9T)X9m=i1=q(#dPta686pABOe*B+^27D#?XQXbP z_w&4u++_&`)(hFS<39PqO%)tFJI07p1_e8W)x;jNY%|pK*bA zNXCG94SN&}y$hS|T0(kK5OzTGczRs65H$s|oM%wc$e4#eL}*SA4gq02W6U;ADg)oL z^Pq8Ps2qwJcX?F~BrA5^IdQCsnx{CWzKqN`qXMDA>gjle9`BrrubzyrzVU<>->Qql ze3J3vFGin>jvq0U3blAEY;RQSHcr*?7h+3h0lpA>E;ixU;>~)z8EyclD;7*Nz4C-s zu~M&C3A|ZcolH~#A=2@}JU}4IAhN`Ru(5e+%|_{sf~_0ESjt+?I^RGm+1o5=t(% zQM3hTjt2)6oa*c$07)qWW5Z1i9=xb1b5a}Xv9j`g4!lgsWw|NDIbjynb3v4Kc~Qnd z%$@AVY%ojRug>%|8g4N52YGOaavq|YJFRfeb3oZfXDA18!YKqWhx>4ra{tM`hrKb! z6d%6pPJ+jw4ma*TAY2Wa@){+CC?!m=44h0% zb~jh|N~pia^Cr5;xCCGL1Kxx4AG>b&I-55SQri{d#j5>~&Twz!oUw*C-7*qaOpZ6h zc$33NTv>10F*)AMAF?^+tRMDU;o*F*=U^d=g?1drlrwr-;|2#g!r9P-f>XYM!Bptf z-~|j#K{YEWMhQx)!jjcqJaIu8IN3Ki2z{%*bLUdlv>9|F`Y!dIG|Kuh-xtI6hkO!a zmc!Ljo>fL`JO)!;DhYG!-2jf&*96*Hx+zzhH^%{@JG}=1)VZ+Gf`p#90*jKm9#s zb+hFA?#Q2V_VOeLlOLP-aDMD`q-^Zbmo90M7Cj=I*0)ZVS6(|ak*AfnfNmb$^&=*D z#sA8Kkmp9)^$2`y$Kb-Ewn?vr4~mMkKU7yVQ(lv-sKcGk$1mu502D~2Rq2TRQwmiu zA~ztv7h2(U&3f(nWN{@RvE8tb`wR^RSb$Z1*75Bj-&=TLg z^NlCf%A@aAF1^0%wf$P<2EB5Fiu>@<(ZUamoQ{=`Jw6e=e*We$Ew)#W?N!5j1$H#J z^=0UA8;NleaQ}?ak?V8{FB71^{(F4!p(-0|Vz82Txzb@O`|$k-I_V8s|VrA);0)I4Om!MF>}F8J0kprLad~ zhKDEC1VfIC7p!rOWoqCY)TMDo`*BPTvzW`B8LQS^yi)|6H`s&X!8;3=PCHHolf_-> zpg+H07ETGVQ2+p8lwSZ{x%>((TnT@wQ{lGBa2vK1?;-PCCo8=a4WU2^C)Q0>VIy zVm|)oC95Y(R!_(4Cjt|_H?Ba8Q@RFX9M7@9jx!DK z(`+!=UOE7b4`bDVND zyc5A##SlC}%I!{q6zPNecmECtXx|VhH#mpRLS9c1c@>~}KIi{j;5S2sd56I>9@ow; zwx(-(IK$kFtey!xJ&#+(?ENY2c9GhJM4j=ON#l9}?so;hw0pe&}E5*403* z%du+@+?{sIXKcHPt1rXL>CPjb%?m1PFcUiP@H|XQpOz<_)^$B)S{s_G-LOCTJq)o| z{mNf(Hj1qu7YmOKpYk1Kba`3EieSyri~VOVIn2t9=Z>F0(R+N;N>0r(y!ZZybiH?~ zW6Na6mRr?Y$3DGd--zL`0AlzV;9SGV=wm1}mA7?g59fuVieF|4%I8_NKO_*CN9<{T zpFahcK&*OKQIawS06#$j*Zc!9j9?Hr-^39J5^syKnN3CAUyw!Kxg!_xW7<*I_f59z zOi}TNh})+vn=NqJ%4)71du8>@o3ye{y{r?bPK1Fv=m&fJqJ5%x+851VmG(snan5e_ zRD9uNeBs0@E#9KXThw^VdkLws<$8fu(WO^(sqwD&-z$|8kZT8U)~5}oo0q=4Uu#~a zH?JC#d5ka_4h7e@zP8Wu7^KEGgAp+mZ<>rZsm=S`w-&!&kKeDx?@yLjjOAtiH)`>Px;S0feLiq8KE`kmw6JVjNP080wR$@^wF?^nQ-MLCJ>@Vv@F04`gZMa} z@lXC)BObh)@k~_V*n+)|tX?%GfFU3+54B?{^<%k!PRQU8y;RMo)bCESj(r|SEvQoo z^H8tf>tDap@9_J>nYB%r+ayjZr@EP@v$+!8>#pyD3Ha$=qQ{n~VZ+e{wq?i9pE>u0 zvKU`PH^AoyhTy)~pp{YuN*|9EAQ^S1{=w~naOxxDpxan$`+Ds_kFqCeji=aKKgUBh z?c_zl6PQ2Qmz$;%n{jzK0J;ZL^=tNm;YO!|(h0)6J>)D+IHY7A{;jtLK+UeVAd~hF z#@$pJy(4B)LLOFUj(D&zA#eBv#%wC$YE>nQo>htfAiov_Ql;5xy~l@+KdKx*-vb-y z3j^TKC~G+q-a*p{1g7Zx`6B?lDNvcnN>EINR;Di6iG5)1Ta8_-r9pqO_d*Y6THnxo z8uU(ztsFeBA}5oOic5>`(VAE5&8w%H4@@>6n2y#aE1IEw0wdjI#e#H1T69pJl|qX^ z6aip=*)Tt_NG6=OkkBJIgVmS6C>bsL!hvTFXwf>jS%d^DSyBxWO^r6s#E`(BzhSzx zcKo61VXbtfUdlt;epI?>;>?Xot#rL!x?YX0H@1G9>2|vdLaW3@XqhzsowXLdwcTuc zgYH7KP-?cvI948Sijzb~))m5o80_D}K!)Jrw?mVG8c|*m6qB5r|DP?ab#u=$g(rey za*0n(ipi#TB$uGsJ6W#yL80W_OgxQ=<4E^&P)z>ZBH_`1@N41wY&ON@aqVqVOfF%w zNioTHBlV}NZA-pz^<}phI=gM4X!4sSrxckp)CZ7*fZCWzKpD#X0@d4C!I-hx^wguA zp(Z_bqj{=x`()?#TOZdt59*xR>RPbVOo$ZSjcFUlkio4}x zqJAo|crvkg;-6`WEhS2h3&h2B>K#-j5Xv}Gy?<`LY#eii+Ar$p>Jf$a>`NRy2_apTz#4~URb zk+VThUY$NyU?TyYm?KpN}sGU`4Z#0sM zM+6>2&AcIIT2GvKTYShd95Z0yWz<6=b`yB{5j=b}BE;h7lK=qm0ZjijVtaA9i4VaT zQL0fYm}_EHkKnKrQc-96PYqb>wZrBRD>vKFX|XIf$I3!vm&N38W&24^kdL7*=Gwei zDqpOXEz!%COqF#_mcb=te5`r=Q`fiO4BmPWT#fQo;A)hUb5>5y84s49ADAc3!?_D6 z1%8Nf043dtxjF>>kE1J7C} z`itjjOY8Mfw&iM6+h!Pf+w#VJa9mQhT`$|N#pGxyhIWDU#r3dM~ki4MBvOJR{)JcMU2DF=?aSLIZcCrJ(VodZ93Kxr*8 zsFQzW0%33R?|{V(tt%lx6t<*)z}O9V-QWrde$Nj69AU&T0S;P`Qq9NvpExtnLEWsr z4nukF%z#~%si>v25lj3>ybc8uv6WiFfPY{vf-BU`8i-7pk{+&%x(fd<=BBFAAa@FR zXkQN~wq80<&vM=4iTymW%zpsdH?YiyGmFx`Kz`eF^b|v`B*kv3t@rrAO&&ICBMuTZze*SWL;KJ^0ynCYT z&4s@DB8YD@f4)mrK1;;jq(w;N@^ zw@PceS4(fL-nji9|J$o%!cEmXTBPr`#CNRq|I-4278BP$Ef7{qU@!as;R0bS1-Tai z!wT_(Qn(k0eZ;=_Cn>GKxz?)ie;E3!uL{4<*C@actAetW=sh>m|0NSSNMF1oQnurr zdGY<@ig8kFZhUXWeuMb_onH~(w@=r!Ox3hc*0gIi9ePcN>HmrQ!+fZESRh$b2eZ3q z)l{@@5(ko;v#~7@E^#jKef!Lr55=8{?b zzlZVb7LG>84r}2mVtg!SAA<4Ywd04?_yXa5(1rPp<$)N#xNg1#XiuesL#Z3X)FW;~ zpdp@k4G)=`ySW+MUb0j0@^nd0KRZ9_2g9(rUxK zRyq&wpqGS^?Pn@$q%YmGwbXyRLZ@smRkV+{3O8oK{@|M5rr zl!p!GlsH)gC*&MH^JqVOkbSyk#{btKn|OR6;0>4T{o0NS^G2 zSD|dLsJRkNvo&drWB8Y97=PR=+)=or_0--Tr)v@86{ES8pS)w!E629PYd%Gs?@caC zmdb0K1iob%PQ|1w2P~Nh{)(SM&Mu{D^)C&-@Z^h6dfm(1DY02fN08%gFjlgA25l?< ztW$hjul!lbZK~z{rtOmVx8UG-nu_~&p^kq!u+G3C(*Ns2i?43$TOiDd|}g1 z*sLT^Mso%uhV81_%Fj#-yCAEm<0 zEa}Z)t9ZBD@E790x{-9#)%z)fc=TVq!0Vfvp(!W;jPG7h6&upe9C5k5Eg80c@r^dhTR@!=8K@#op}}cG_@oHkzOI z735b;S1x!V@?r!BG89$_FcwIbR*bJxOPg^g6SXr{b$V6nSP1gOu}u>n`|890>ftXR zd->Sdrs-;I0AFZ(u}w`hXWw9ukL^eYX>SIDw2HA%x(ub6vOsiO)`m+U3XVuG671!1 zKr$7+4VJE$qOv$V!@}Qm!|a}&sS;D*A&$@Cj0E;xkXz2-O7iz?$Z}MG2(QXG4Q_mw z@xK~wHl|>KaWu)7QKVtn;`K1E2$#^#AtYZxcBtl4_)qvMRz895w*sDF=y#bSpwL&N zLSMl~+RroU~BAp@Xts-f>Fcw0Yb z?*E%WWby{eL4ylLrGKkr8RBCxa#w@`T0A)yYff1c+RzZQ$y<7=8ku za10wc33*-_6Nx;_8DFG`n$|K@XlB;&Nt9F1Cn3CO;FFN~i0`1_$MF0n@@YgY77+xp zIKh~w3_)<`UCEl6ET9Mu9GT}vB{(Fl5!lV=fJ46-DZ2Qc*=wY8tmm~xei>7P;(*q6 z?#A;@eJq?`Iqq! zEDN~eJB|3Lw4^1uU}3VX9Cx}n!LQB+_Ir%tP@P#N#{CYoqd(|{c3Kf(jQhsmg0y4- zI{^bgj1p5c1|cu7fGa_Rl_11fXaPF`1L7hBKby${c02=&8d#HpZ3z!Yc!#LUo*8&L zgl}=6D+wZut|;W}vw)p|0rjE|a*z(ZO<>1c0V2x4uEeQWmIUt*csIww^=*VAg&=UK zi*77jT>TNsU7o@eMkt9LgbIHV+>^LMLk2++;qrQw*xVs<1m(6BrMG@3RnUXO8+rIV zd{1D3kd&AB0wrZ2QEm4X9hUcs|HMV)TTCYww4d@Pm8})(+$djTL_fpCr->SgeFr&G z#x{g{4q`=2l^&-7HNZZ`XSD~$=(nzoXAmuwVpe*FCCIaChu9;8&nqU!uAh(wA ziTpFT>VYxQpwh~KHU@+cfW5i0lp*Z|f==w<({h3p1S<)Ijr+4~_AdThMQ{%R=^AAX zKq_uZG=9abjmGdi3U2%!0@?&$IqeB&M8Mk8u0yKQ#06c9*WM&6Uu{p`(upB?-3n%y02HL za2RuJ5&Puhj4n2M6ZUXW6dx4B`550NFH@myTPo1kfAPHX2!9_ZI6-g{fKCC;juC#V zm0ku0b};!VCVHOW1%j^-{8xhiM(`toAB&%?h_L08`Q#(WBPb$RN-&FbsRFXb4i6n4 zx;UuNZ&#|MkDN`h)$ch4jwe6*IVS%U0hV&}4EL*iyQJq(-w+NH8_zZ@dcrqDx?=4RKqyp zC4(To6W(}!p!edrzD>#*;5O7w8Y}?*fr|xMPD%^atb0a^j)=dcR5T*~l2Vmw-ASoL zweF-884-U;DSt%#C8fd<@t2eeM#NuIimTRbXNY5$WFP#s{}w=rB(G7W)$ThfwW+yo z$naT#-!4c<@?uq51RlRrG=i_J12SSpJH$0;-Dcz%b@3ha)JU$$RC3y=zezW^dO6yeb zo%a2@jVyWzEsX)T)O{zVI@Nn8rTuEId&VE<2Q?-G?P}INQ`Mjb%4hr`-CsKP_@uvH z_17l@jcV3C6IiNx@64C#)qv+tdXu}~o(YtrRO3ztVk3L`mkbn-+|R#c;9m8^?wPJqRbNc4Wbmau8lxbHiB?KIe|z5=ihwV=rj8HoeaF z7rU`&>FAoV^;)D}kJOKZlaUhsynaNDbZU`KJ<`driqVbZ1zMy@k2K+Dpm1dO=*ds- z|Lpz|d8Tc}^~E=8wYE)q+oq8MRoZ0SnzSh$s+G~hUa-k8gQ?;L32BS`fUIslsBJ!^ zZ$31VuS$oETayl@Lk03f*jr`6=D1u2_KXKC-V>15q@~<&Z27E+nRCbYh6`jckg~xn z!{(fbYH8#BvbtfPwqd`%VgE?f9@3h$KOK*;*laLf`eOYo!{?mHW+{;89@Hz==qvW< zD-NrHS~UR3TN7}mp$UQM&^Et}zRV5B{MQO+MckY_#i5XdBe>R1+=rvQu3x%Ys4w5C z*6h^Fc7b9@hxW>Haazg^$5zjZm^pX+Cw$Vn%{N2IKs|gQtn)#Wd!0{}z>MUetjjTeyOLaLJ65Xf-Eq082aP0jF@v`*Gj&~NY!YcDkn5Kq00%_ zRLE^DB08M9dLj`|K;T)7NKblh16j0kdhJWyBnTlMRzrW@ocnhOI_67(IFQ zu~~-C5jeRpr6QNh8`F{(bQa6dP4t4!W*J(Wb`W<}(jJIPt!QW?6F*>rEFkKAcW63 zk&npBWiTtV0kcM9B4W;o?UfhE;4Wo@@rLV7dfS#+M$I|#_sy4nV)>0Oz3WhRdNHGJ z7HTVZ>MM5=_3SimP1>2nWLtc*UhBM1@4RoMP?hd8ZcVx`9ZwL~W`oh)oM-Df&&>Fa zU9wE3=KTMSuAMbv=e&uI`1Z@heYxQna1&$Z-0>%T{W7P2Zm5>G&WflxcY+gsY1R50 ztJU>~wXP$2*AYPr1M=3SBkA~J87gYo04}uUcKGbJVm~3*bHT_4W2a{sI_E@flMni2 tFjsTKvC?b6?2Mapr#KZj9G1bx%MHgqF)L!`-0|n)QgMT^RTJ#J{|j)il2zuYdhUFj!&3^@+dw+hc$Cvd#9F^q^cG?y=vT z^4e@K*&enDHo=~@W$bago&1ipBko|o&bX8Py5cVO>yEqGuP5$dzuvf){rciQ{5sSA zOhvpRQyH(!1mb~AFdoc=;-O499?nGKkxW&*iskQ0S7&PCHO%i$*JkSCb;xD0>d1y_t@9 z2lEHhOEaDE&djp-vP@UJE7KkC&h*54GRx!3GqHFqvm(BN#dD;4<9)0?E7@---JcnV z4`f!wS7lbmSF@5$U7zc;fjzAZBtA7t-q(?gl<@$JlCm)?=t8Q+=N72lQF9p9a~ zFMb~juTSsE+#kQ6`5V#?WFCw^$o!4zhcbKP`Lp;Bk?0FY)SePnM6F1c_RJyUOm(w;7#_PYrFp7P2T zKeI?q8<5jo$mvNXy0NULoX#$i(?;ZUH*%V|qnsvKJvJfDX0-F5lIFxyiqBY%_$0oZ z6Sf%JB7RQTntEE;vIU8R5n<>#SNu~f-|fhEN2)uOZBnwcnesc&;_XDdU8(aZ^{17H z-*utw@XxRKr&+w+h<9J=(}?$s^2QYJ85VC3;@!{kdv<|%&#`z9Al`$E#`_G5_YmUk zMZCjWJy3?vE|B+US(<%Fv)_{Da|@*T982>tq&a{zV}|ccEs$o4r8$T+hb(EHUm(r% zEX~76^GNDrroPzE-aU$UkEITp-W_1?9>=?Q>QU3XN7%c=c=z$tKGVCsY`h#Xjh7eL zcsWAjg{A!j(k8y^K#${}U-8egH&5VA5^a4!2{+|`fyFwCSi`A%P4B+I-U)b@N+nG1 zzL@%A{7Zu4pe=Un7nF6(UaCxvjb-!6{AhM8w>Rc1g$8qH$A)(Ue2K|?RxAbC^Par? z=pQ_j9L*<>rc))~_GCKEd==ZX>2zwC@+kSYXT|Jzesl~GSSl9vVCs|Osj=Y{KIqvs zo*x&q^v6P56ej%Ap4yTj393H%4~`xiOQv%%2TCglVk(#0mCTH$&z33ifAbBzVZBUHj^s3A4#UiQ!!VmYIs}}Q)Bsrn9b%B z`DE^7DWC+gry#XuLQEwE){Ok|jL6#;1(u7?N{cFs<6{ZxoL|sziFry*+mok~!=w4L z4~}L=(Lo2P8*};5;an-a^E5uJ3kW@kme4)>4xu=E#zwNGibu2KX<;ah_a$fY=rF!p zgQg$NB+g{TlPNKgKTah?eQJip?8(&FfmAL#E)J)7wX254b7ze~HQUqKTnbZKAFp!f zn6Pi;U>=>FbpBO!LdP5?Ik0;S{c+oP982MBplgebpvx)4{6Bt+tj1#1L z)m{pl>Wm;at1CP%sv`{o<;%OrlcG?nIhe{MPaV&SDXsp9?N@{GP`N#c(V0FtoW;O! zmO^{>)5xL0M2%kxKD=Z9evF$`o;}t-ym!xIJ1|6#iOGx>j!y^JY#E}cV?rr}>h2SV z&gN4&8m=)6`G;7w_OV(WL>#q2{P!huyGGNgv24uo3!)i*K_oSj`1dFAm4l~J!!d_= zAHArg7xg zP-=&Hl+6u_$8v{C_Wi@iSG{Di#eVZG1ifTS+2VG=7I*kU|OfZ*)d z0HDC>f%NFnfm3Jm$FpN=`&X|X$N^TYq_F~En;S@uogK{%BnT>EIOYZttlp>2ibs(5 zM2)Ti`sHE}*_W$_bKdrz#}=vo($g_~CYCLTr#O#2c1l>CVVU^)PD z;#IqN3?VuCUX;~Eq}(U!jMb21KTT0v;GiD9z=iOvuVcp7QS^06zRrTLb1qynRmsX< z@}-^}PUHdbZZ(s8*Z@e5C=ePI)f(O_uRSc2qqk}e*j9P#I-1R+49$1iGUJoz&e zxgE}V+kC(lslD*2*>KNHxaW%RYR~H%is2zCJXG)v{R8wqjdVlrdxjZ?5>HZ*bRB<& z3SX`7cpmWuir31DF86x-jIX`ui%Py|LAiOiyGKCDjKEOJq86IP&XmeC9A;1(H zpFRO(LK=jhrHnL_j18>gxDfoKiVquJp8^MP zS|!x!r#7BQ>>$cVvqhYQ1NNDEp3j+ui}huSS`7!q>Re8fTx~ULUw@FcQs#1ycT!>) zBy>u!G}w83dIIE~N|W>(;(v{bXK1y)g0JtRDOrSn38g~e#*ZD(TM9>$VxrYrI4#N7 z5#y$zd;@z3-;?f#;4;33@07cPK`UC6qV!HZ<@s{?!Y3 zf-d{bA-Ec+AT$Y1@BmJsS#aUkCA0_u{JMpp5V~v^T7|mjNU+bJ+Q0*NAl?sx7H=>4 zi8*DAi#DnZ=!rhb&=bv+m$04yA`w1*<>dm=(+QfJ>=GQWIgK7kXs3t8W+en z=GwdK5V)xZu%4sfKta`ThAMH4II3LC4Z0k%i&1c~DI_cfFlfgTW8-2jC7vxs6kj64 zr5a%U88}bmh{v=5RhkGB)oQ&}BJ?$c=T^c2@z&4^xDmJ!T_#0W|7=+yx~~}BCq?&7 zxg=lPTx*nmn+oh^J!NUJXQ`7eBd-T+c1x=PlVZ~FYg%nJC4_#zi~sMb0nb84{*?0( z+e^;Ry7VoX_p4Ee=v7RVDt{@Zwy+Xv@w@JH?0LhU)%zEo;oJKKKGO#3~>_H9!8wnC%%M!evS z)}AY_*MidWpVQ|?&~Ls%dpe<}GIpBaXi_8PmXuF1jpaV;WgJA4 zu4f$2U?81yJ?%PUKVy5+`MB+jy|YXmly@=b-d(?-fg1Di;Q_8F$%%D7X7=J;$(=iu z9)-w={C-ZUfI7j1<-(XfP6MAk&E7#N$MbaWpZ`;@{#$?sYhPFwF-l z{2gyKwMk9=vrQXknl`@P_{Lp7+f{5jC^a1{)L8Do!TFG_s_|0&TuXFn$At%{9(@13 zur0E5-sbXGYtCFv{Y!U$X9QQ7fDKP zMa(h9SMX^@+o-|;>QZWY3>y2*PrzejI&xt>R2S^V;rNW*K~qN^@EX*av>&riI)B}M z0PD)rG!@O| zA&X84{j3Hce+W#K0td#&@}n6p5ETi)mMU08$ThQL3JXdjpI7_}d?pt3`v}qlEiL)a zDe`_e3JW?3GR7aeQQbZldFUOdqbBsO4GxHuU})ZF^LG%e0=F_oZ;@~!Z)P`ZC-Dae zFf}N_`iZbMZ&}1YrFc)kk>@O=SG5-wZ_oPJ#X~P1k?NLTsV&rPyXu0&@7LGK-te}9 z>Go}7Z7b4hltPk!6@GDw0(>GH3BN%BG!n#D$x&y7M)4>ye@l(|SeclO2t&*-(5o+! z^CfbKoDc~UiUhz!8eSqbiJ5F>#Uh8=H#ZIEy!toqa1t$RbShj#5F4F9gyI>UK3ik! zyuZ?Y_q=T(r`2}A{)m0v>0<==ow~efsmR0lS1*~)u-{yTpwH>a(1_q*WN6itZNv^z zGyqbxS_l&n}unFKac|bbId8iWt~1G7d4nYJ)=*vohOE3aD86Qg5Sl=&d>OIuwC;@( z!%XhkZF!gWP6M#hx=`)CF@KPU1lrl9ie|8W<<5BL)0FZ%4HQ-S4jIhPiTM@p9dRWbN*n@=1MI<=udm^BX z%MZ6B^7CFL6C0sawRbi0ebV)s-MDCtcTic9~Q=a8)P-HWve%rNHL7K;*(cIP9*T3si#*dGV?Fu+6{p9h=Wz@h&;@Mu&|( z1(W;^KE+W>fMb&1qX33UexH1-x^Iw=)tTW8sBFr}{*7=A7AG*G{TRZEbECTJ%G%eq76KcI*Sdo! z^G+m1REXUI5hCQ<=V}_J9(cRDtq^F-MNzotqFuIE!h>DTe;pjOJFnTR;k{N99E>`z zMcwd=Nkp<>dN!W!!y79}eka&nKbAOjW<3T}%X-WMT^wk1SVS!)d~l+rY@72G(5|)J zq<)koE}`lR>Df@nOsJz6>XbsX{J7A~r}<%|1=&yCFBZsQ@T*8ZMqPVMK&%voI6zZq z!cdx}xKvOx>HEhNMvjNZ#Xfix*hRl@xjGB%F1kABU6t;3qGK&iv)#RnfLvLJ*MPn- zjDPiVa-aR?3V0TPP!&+HAdzV$;1t0pKj2fKRHZ45D8Q*k1y0&K-e)eX@@GWWQYy?Z z4~Aw?j*kWm@u9OQAaWQ0k;4Rt98WtI1w;RM)@QH(T8^Qw@P( zv3jLcy|NHk@V*nM@c{sf3`4qY-wh9TJAW7)bU3d$s^Ps>8yxI#Uh8nf|BnPd#Q%d@ z)VyHLfJURWIXT4WL4%6_C#8D=&R)QO)-A?yTz>A0e@4mvlALn${XftPa-iC8%iRx; zalS_jF1m}Z=)B8Abc)fz>Q32N&Za+~>Xi8~{?&`d5ia}9Ik*cE5`q8-9;~f|@ax5zN)>*6DL-OVTXdT$5Z+3fSVRnKqWgFy!rQR^ zVh#@=yuFORR*;1^SmK9-MgXQICGUPQI}EMMi2wsf@)M->SjnUCTTMhhksh4Z?TSK( z2V|5mI(Dm7iDEz}N-QF_1gMoVs!IUVs1dS;!Av~Hv()1EfdAz{P0#lVcJLzTeocvg zy^S<&G_FWoqJR3J3n45oxz{n;C@=NtL*=DXbSy9R>4WDbKn5JydquR)d;4 zqVA z^Ji=d0)dDa>wj#q8BFOm6ig)X0f#OBiF|(tr{p3X-crz@3RQBQ90jf^3;9Cw?C9t4 zZVdsWIXE1F+z2*Ky9&XsVz5gJb^!+Y`}%4WNz$d<@j>fajMd`!#j5zd?TDJUQk8Oo0;tWdPH_-%i7qSZ$fWuWNeo z$ZTEDOkGd0E+*B*3SrCbi!p3zsS5z*hgX)=#EK4)%3tzBWh4VdUi_GA@n5MHRZ1nJGqKSI&PzegD?g{DBQ=?T2-v6Q!Y#@Af*wMxF$ zf^xI+LWPEHkPxepiGc?oXR|#dC+ZfX$Pb8(`t9T}TQqf7y6G*j}F&&VIFmC!L zLLir*am{9xMvf{m3KT<*{R^G{Z^<7vi7hzm!nhWKu_A#e4hLwWh!@GBaVgSp5J8~X zL1 zM=&}|?d}!8a|Xv_cN3;HI0$Q_Fuj8?Yg$=LPNzAi(^2bCb=Vfuq9cKG3w?|`y7Vn- zdQc8_H+OXJTW|YbO~sp;T6h@$>P27_m;GiGu3_=f#TFf%Safu<#YPwSC3mSkAy2CP zP=-Hvd>pLJnXx@%kSC94pz5RzCc{)FgwG({eeiq~D|&jQ`8x6}`I93+hY9R66Mu|n z!@61}2GYdx#S7lArccq>TY@~^*DbU)&G?#%z81;Xf(guT-k?mB=Qhs?`l9%AdF8=RZ^*%Ja9eIG|BN!qX&~r2TI=!!eY_BqU#VMJcN9`1$?|yY0@?@W@E&d?XVqbJ7=G?Ys-7*YbWi~9wmkT*U0+WZ5P_}VeS1w z3>&`CN?(}vX>m25F;8RpFSKE^Sy{IAafFgmTRGO1zf+hv@xS0(F+X2Zbm!8k)Txpy zgS~h}PmhS-!dnhg8PTvP&eZO?aJ>}n z09`#7X?Q8{mB5!nFNQ9L-hbP~I6C~u0?u3u<9}%3BG_}$J6GTK(%4tViuK)6eRm;J z{w7|iXWpq~!SZ>BGJ~d(oGlAm++nQI?c-OXo`{-Ti)Mdr*$Ufl-aFLeycUZNHM*}? zRKkC~(KXcSzuxL3{}Ma-qs-rJM@V@%ybGCW@-`tXxFIET3K7ABUsuX4RFPoaIQSq{ ziwJ%uRjX!FHlGjzw61|F?;$Kt^PR*GjXpU#R;r}g&o-^5@}-dWmNsPSW;y|ENZzr0}#Z`5Q zKTYxL@DXr0tvy_SmFpBw1*QTF3YJGWCy>TSQj1=gkx;K^XdjOHJgq_}H3B@w#un^E z`eC+t^E$Zj47QlEx{H(v(6TX7Bz@*!P`Qh)za$X_Og=eX}_wye^`{5HGge75BbhFO3kf@ajF?mKF2NSK61z56T?EmMg6;p7MCMJ6N^mqNQzw@nkH0eSN4PDTUgBB}35DTMm|5QuAP50MsF z*f1!$7g>XBu(Sx5u6>Cb<9_5Pizlo-TQyUOzFaZavV^p7Axe@0ZL@*SnLuYT&?NH%1(E}@tO;L|AqHY_VnbX&T&Y`hn#w+S+W=B%u{ zIQ;TDsby`ka-CGU4(QZh&sOUTf&RH*l@x5B4R+0tptVN|_FU=OH?xd*Fg>CVrz?h(6DGU zazL7V0Y7HV%_!x?xV~lNBa%eyC7(dPC&*#EUOk18a~}V>=Ma8g{hN0AU#1-~2UrJ`CSv6?)~>Nku$} zkq9?zhSA3}tvn%~3k6~qLwnA>x1bu6gwW+!l=RSURgftVddg>Cb&JHIarLat@RdTa z8!}AVN{M64%0*>@NzvGYvZBq#B~#m?Hi$;g>r^D`^lhk;2-E1an}dj~=i5j@@={CD z*CqLA@8pg4-Ya{H?VF|c%|t`A+-O;TrM1|yL2B7R&y59kvq1pChuy}tH%MZ_)DaAQ z<3Z@N)Hk=_u_7T_onyOVP%M6xU->fkke-o%Zd9LT|I3ndPOM6)?XToczt~!iuW3vb zt%-3RsWF(Hn4kq!q2>IHy*$H0eXl4htizWX-YdD#yQev@ zU=x20G7|p;j#2fAskcnj8v0Tm7q1|%-2a0VGVUXw7oE5H{a^^laX5pk=Gr=>w*J|+ zwKHvNukIX7hM-!@876FVtbHw7|PCEq;@v4VkWZU%GzRNK#B|$EH?=I z_lcWWMZctN4>*Fgn1+`5uv!kaMDLLAUGd_)(uvO_au@P<9 zdqt)d1lwnH`@5*jSL5YJIE~%gk80Q~#Euwl(C74M>I|ps{*p%YJLJ#+SGHvRIRZ*9 zidCv$s*?oP@?0&4fN7L24#p^hi7La;ClL7CH12EQ=*B(ppwExhKsYyQ+Aayjnog;v zb7}|H9I+l5jA1fVt()uVm3lVL_H3Q$+4{Or?Ab2$Y%g?}?~C_ey#M_h4WtWF1+qeM z=4u;fYx`$v`>*7RwQHr?wFS#9Pll>>d@?k)Ub_F%1D76<8kS#l%?E8Y4ZJ9BrKGI5 zq!Sz?onT&itsdokY(^{=HFp=_qX#T(64&!eWk)8A=#8O91pk=EMi)vZj}2b{TV`i{OJ{sbU)k`Tdy2j_ zl5b5xxj7xvhcwUwfU!+g6OrLEM#B}6m-se0Oomy09}ZJNWW#+sGAS?8?58*6d=vk< zr;#Htu<}Pcaqc1#th`fEK~ncJPNSc8lpCFTyL&B$?d=?1cPh{@%A#H})Uw}fN03g! z5@M1SqTWbP$;I|@M@kX0lck@aB~K=I3^uMrYC$|CpBxc#jA&MNM6fyE7fr*C*T zMDlf_Qt=U5IHB@~6M)3VavR%4Uy_f5$U5gb=RW5-=bd!r{FCmSH{Yz}OUmJ6D?y&M zY9S1n`GCxH(q--Kq|f+enLP77?PJIczuHFP3lj@TkQY*Xnsh^6eg5MZUFZDgD$Z3- z`t!8!O1@4+6yHfUDsz#^3d8#<<9o3&PrydL1l0c<4#79+|AtNQPgZ=x_Oi!V7s%0^ z(=|$b{qJO@V9Up}kjYA8%EjIpdJY8l1c*{Sf;Z*_x&EgoUHM+!w@d`_2-%OU;BuOY zEEe~_qlYGx zeHKD=d@S`O?A~F+Z4}Z4=sYCFvr*avusNE6S|RM0MYl#L!hO+Ulp?`)j!{5J4j>y= zc#hSJ%L%$Nm{Y-wGcr*`$(rAJ};a{_PJX4(!=|-=TwS-)hNEtQ~`L zB_|+Z$wiZ z_EMT0O?qX=U6k1;JmARQ12TV!8-^?9HWw3ePQBl=Ax9J{f(*v`c4$f>k zIM>+zisw7wtDe_ue%xAIwX+!AB}I2(jh_k1{R}C2qqN#qZzSp0<96;A1ASBXU-D1iJr{0z`4Mn`GvWS1xc_SGC#R)*_s^`^ zUs$vMMm^X=d)@u^Hy)*$-jAf@&MoT)Gp9Y?vs?f8j?>vt{jLoTD3z+}`3hSw@}-Af zc<55Buy74!`?Nmm48( z`rQb5Gvp%w64#DS@0;CrxZtRQm=aWjr8d zRKh@ehwq!vzf8(_p7t<%mj!+Oz5R#1McB#2{ zwt4ML^V+$l=p{eww088sYSfKrH{7{s&%D>w);{m_G&R5D_O}2N!U3mPcRQyR2e`Ot#RxOIDcBdX-Adg&4?ZTH>)ak zY;wQZQnzEh`^{Bu3R&-_kWDW5{~+Mn8S(x>jUDb@Y$j(U8Dsc~E@MO_U**AR8MN8l zh*`MOAQKHFFzaQq`gD%p!Iw{~*X!G7ev= z(AJ#A4*CvYyLy2^8ABC|*o7 zCx@A>H>|v1IT99(nQ?r!CiALSw+@p+D$W#C6H!lFlwfLEUZoe=Doqe3;wUe^NTaOF zjH0>31=eMnEiJ7s&bZLR%*dX3aR$moEwfE`%{1NhdPT8myVSJ3=-VOrb`*R&ZnUi^ z^zJUU-6yr(N2@br<3dr|<>Q#icu*kqQrBd#bw{CibPM`-x+b$QzWzAsanAk^xh_*) zTD>6CZ!b^h=oiE_YZiu3m1Y4Ah`FU5_JZ9^I!4~S4#1UMh$)U$kRqOpFtN{?28)Iu zVMi*JC!uE+p@WE5s@$`G|ABpn_9ZY(N|kUDd-v_w`QYH=On8X3XogT};jiRQs9d6H z(TH>@CmO8-jep*U?#X!&MJGUq_L<9%wI6cW!cp&l)VpQ2cl%85_G0f&sds0g%X|YL zUaY+I@TG@8g0&;B`gJP8JLJ5pm1rR!!w`m)yaoZAzjoF~_K;sbEiGC7!wu5foo{@y z=-VUt_7r@3ZiHJdJx~lUm%_w#G8^t#Me1>0SUTYN0eOC_VzANuqq@Nw_q7m&<=CI^ zM!>a3C;59^gT3Bs{dTy}1!q&8z@wrIPSfpG^R{)qu1nogUOIf7-jL&@z99=A2I;WF zy$3AXqOQ+JqTt&)9Bt5-J`%K1tr2Dl-q2d)R|8>)C#i4JRq+II_; z{5ZjduSET-=nILYW-hKJX9JuvfTvomvkGrI3EtdAX`Vnk-fHD$$mB&g;C zXv7!nLmuaawSxi2wLrz-dME(Z4X$!u>vbde+A24NtarkH-Qyan@Lmtv;c`PHLr85P zT-1qCz?+381~X5K4&s-l_&aI;B81DDA#GS>D5t9i1>glZUz1!}mLS564wE1Wf8m3JYgLamF!Ftj)?)Gc*<%RboR{Pl{#O80AZ zgC6%a95m44yykHu;98}V{4K7*CEjaG?Qlh=Y$9t7KZ^katzpuL5^30R>M#i(q!1>t z(s6pP>6!eT9?dBH)5uRGXDRgs2`>yx#6sF7Ozot?LuU&Zors&lZtHM_PT##lgkGUT z=#?@;53rp%n!(m!sTzj{l4vF+r~~bv4`y$%R$fK%ccXVT6wg&|(fI160xTOs7Xnz= zH=w2|uX4K>CieqGmIpUwOwljF?!bk>n@O-IgE#xrb_U+?t1XaxI2_rMBXCs<7_W==X89W*)6IKS_as*4?{b&&^iLG`(frt({{pZFy zGnt*S@+yMG;m&#lyB*W0JgXc)mwb5mv>1ZbSmjB_Z5U!g_wuDO#N}7fOlp2IvW0D6 zhHROQV1<|XC6FzaL^WjlS(-5#6#E<=O)@*i@-|zCqN1R7kfvHQ(&-@CFUk8}I&^X3 zSBm465%1m33*GlRe!pUHx%-;GZm`pRt=&C%xAR)3n?ja5$$z(NaI5#a%?@`F#QQ7D z>Wa_Pfcy*0mogk}Lzz)X$n-G5gU?gK3*_ioID!od3rBv9g%itSkjs<-IS)~uU!aHPq`+OrK>Ra?^2;>x$kGZbxF4aeP(`Nylb>3A%NOxe;#bKj&pCB2*5on^b&^{A zMatuAp3gRWo;p^lOm=b@DoVN+Wlm$oM zqSxe5^IHg7>705Noc-{pzkTcuGulRc3)ig;PR^dxjQT9BF6)dVl) z%UBa-W3)rOg4iX`Xb!tUtp^hSCSFbicwu>z&!VU|>yam{yU?-Hv*E6pa91(hqdQ;P zQqX6q-*+I9m1e(_!s_J*#)2tZu?v0`1XRM%Sw zTW()3A2qZw$WR@17=Hq9K6tyIv+MWA!8#b_$1WWGgU0@z+IN^rj=eaBB}m8U z(5)DO1GCNRW}4R(n>R?!8>YfH!tGZQ(#rb_VJPoBAcY?&_#R;GV`v&=!6y{Wgb&^{ zMuVrUmduZ_u!K6YPj&3a|H!JL3Wi6fosOOPH zyZ}cDrP^DKh7e%kIz%)V_;{lx6sZ_yO;eUJIiI3JU4-Yn`d9wg9>pvOR`z5AA@eZf zsI$gMFP2jn)TE6Lj{JF$=_Z+6pPf$ASis?J{o`Q(q0tpuQi^bTV9p(8vtyR|?e_;Y}i0EZK#V zFasmWTplW&pBx_*Q{um&#wD0%#3Kl$5oQ3}cvPG-p;Cq*{Ioa+J1vfV&oE0E zJ_$Ss{Xhksd<|W?5IUi9siS`f9x(dv;NWBkKmH5|x7<(~lRZ2>cq%ybob*+q4te;A^Q*(X*car8JgO27h3R7|auJ06=6qc|cErdrNMkK-)* zC>0v9V}m?4wksn3;*r^bUD#Gm1=o=XrDoN#5v*|1p`zRbQUcp3CYJEV8P1O3%;`Lt z=`=>TOwF|n8NxVkW#|G{?sv^p?kZI7nrqlOwf(|on4pw`LQ0#?o=KmiohUkpC~)dYmu} zh`);xivJD{_L<6{ji!?L6AEWDneC2k(00crMn`Z~7Yu%-=~(5EoGLMvB?3SsBBta@ zq_g>w>r_%aX=Md}A30BOz$K^s7LDC|5iCFD~t65 zQhga)Gu-+NRwBq!W{|dY$_}$rGcXewxaurM)=80dg~+q4iQ|eZg1eo_ElB1$2<#Y+%JqUPL;K&tMZt?r$v?!E1?KsYf7YRISrod&Hq_~dM$cP7w#WqUEON(!th1Xj(-2R^$I z2{mD-TYi2?ukCvkgAwNs>jx{H*DBrcUfa|(RA;+hw|4u0^QV=5a%=0iuW86kd}%Z!1}<#v>W4D3MW>r^>d2^J(7~nM;L(jb+oz z3W4qq*QI2E;F+d2+so0xM(0oJ2Wz;(xv|p-o3T#&Wmzo-2s~+^w3O92{{KP^RLL5M z$M`*bS0sMGici!M5g}*9zIQ%|ct<*9@Fb?vsbrah=zd1U;_yU{at&X>1fh68|?iMxhepz{0Gj zH3sZWR4aD?^(xDN&E2(2y6eG05)SUSD) z%DqzWeb|B@!D**(2*6cv<_Bt!Myi?-k>Dpyp-Gehq2I<2pU>)+J7$Q-z%o()!oY$_ zV@hS2N&!~C;Y=!jJS%XdNBD_@4c1&VyjZ)MSt;TRSP5UGhItE5=heTtm1{8ft%sm$ zVIJG6^{6{pS6s;P**w)`$Z;3rp%j;l*H=IHaruR>nk@7io#kE%Gdk7fSvIl{ZM53& zrgK;qa5!s5^&ZB*dbzld8Fpg@UWYRCl;xjX>H3i+En2)O=WQNuD~M6;leU_s2BkxQy$)kS$Wb@Uh@jY`W-Ig>9e3!-v_J$q#sj z90(0z*zTso)f%p+*f??xU)C%!nGIi(&EEnV0NfBY0Tzf~N7=YIBSk*y#8PcSZ2=uK z>E_I&vHkegN-7UEqJAq*wVH>zyz{5jjPwO4L!ur1A?;A`OKn$UKf^`|oDTk| zdz84({wr;7#0t$17MmZGnjbWxuu|B$7mE6tDiOTxu;%ZwYLBE+R4@-4)z1pc_mYPZ_$95L0lsz;_%ln5`MNiHd7tr zJM{~&2yMA>r1uBmB%J>Ke{fC$W?KCH#2i$kTGt{?gT1zEy=#Y-ID;8MAomY4_Uvmjx={4y`I21q6%0v672tpdT|%3Km@xJ=OEkxw^oK= zrqCJPHClb>P;rKw{+_Br zCRO;EOP}J~Qmyp%hbhShIdcI?~w!#gujnQdz(YlAxQOu@e zTeY3`R>RR9Diu=?l_JAnZtm#bchPEzmGpMFhZv=QXD%P))L6s#S1+PGa6ym@S6e56 z(%v$8b)*ZcBi^`E7t#%*>t2xJJ+xYa6UUb`lA1{ISeXNaeJP(N=oD6zIWm}t^^Hw&JaBHU`B16=yICr>4ZNAqVNO6<-G%v-%$KV@HN0Z z$EW=eC)mj948Mq!oV1^J+z(@%daGfYsKP9AGpFWw+lkc+Q^_?_oePqwn-syr0xfVH zQ6?Hq`KaW2B{jiahyuJGumx%hl}qN@yK#2MzA5~@RkNf})64H0?MtQhHCMM3+qX&W z+msmP5!SObTXrBm zhGJ+)3Jn!}3*Nj%oC_M3M=vArsHBO9w`8iWETTFo`k!=9y72?OcYTTqlX z2oI`Y27YaAwjB?cr*xe}0rh(+d=#g>WY44o84g=!!QWEzEipHrDb)%~3-%X${nlAb&4Z|S z)Tv4dBgxar(RA`?I<-&{|Bi|nH5bvGtREj1pG5(z#rjC8VK$u@HDw-&j2CLRl#?&! z$;)zUs3lujugfYZ-7`L%tGis%8CPXBDEZ`05XHw3-!Mp#32$ebns-7#n^A`qLX=t* z)-5}hIGQ@1Ophe8BXX%R0hzkMe?debmJ=Jt%O(LJ7!CwUH{b2IY}41PtZ^Hg?T~ zx{9G5DMV)hFLd(?(!f+M>Qh$1`{B9M3YzuoG^?=9B%O7*?WNNC@@ z-yNxdg$-JYgG0tL_);7v={=lJd5a24%!>Gbk&i95F;ae!_eqLQVgpDS7Ntscn_^y| zG@mDjNf}%sfqjOAv`Am%!Y9l!DGo(xQiBmEL=grk z0(W$I45%Uw>>0O{EeJTe_p3<6p_7i#dx%BsZk%vybP!ffnRF|~(>r&ZpO;oJ7jQV( zp^hvyL5Ycr0F;BB6K6y+ax4zxwR)ke>9RB1o0>f3VI2LIate+ucqi1dBW7J#=A=yr zZds4igJ&#c#=Y_qrBA2<+-QVSqAjXf%~nWyBw+3BXyKxyB_}1`AH%k2fxppkQvO7quY%?KeeujAvqMLUOP>Dpm4D z+QlHZJ2W9a;Q5zGORInEnpD^&*y^Rlgi>u5My%z^D`)75BH30gITOPfk$5hVm@x}Q zMsIMuuCeRTATrlZr-tNKA`bRP)HFyneOH9nGKHEgXd55k@8!nXrrw#R-eS{Asc9tw zLqLmDmAu6k1(3HYkK%l3Sv+Oo;aR)hIWGWaJpVvlQN3@NH(bHK2PMCaek`c!-WsxLbkBVPbSJ zClb&wBpFG$j*wrCQdtObGn}Y2F)_S`FC!Kwdym3%r(~~@*w7QbX2PTVihz?1EmjX4 zZUQ-nNaa%SzlY}Jc*ZadgXom9mF4NvR9O;;$#if-%ZpFXHVn)(3=|tyOAV_FRpxuj zb0b`T@$~bby6~xjubuS>Z91U&FFN2T2=@O&*W4NICX2C3DpnoKsiuF10`e7oHoe#w ztE3N7?aW#=^kI>lN2qR}MN$pPqDx&J1$Gx*9rG@`8@s)Y4)&$dIfDiV_KR@Dv(bsz zDT>j-b_G%&E${HDN(CE6nbZq4pv!)f1Zf(2fUupPI^HFpiPg=v8n_|ICY0cTh#lf_ zpoSO|c>5qmCqcI#V)Lc=tq?kaD*8$lhf=xxfpOS65=&l~0Uphc)!m86m}!P9&1?H~AF~jr_Qf=P%W@g}&iG`^@B7QC$CQ7L z@?By*wR$&At~%;4=P~T1TL{n_dx69Fr>PeRB6Hb$1gE59p7~=~TeqH?4P^`8@^tXPFlS6)<(f2|5NFPr9Zu_h+I`^|^hfcl zS;X1^&F%75xM*N3a%`uF#samp4n^Q&CW!zsN{{c5LuelF8OIuu_iQUu-8GyQv!zgW zJU^Vp=9S~wv;e>b(kl-w0;aE-^B{SYU2L(p)Id8~5_y2RTp|geF*5pOeq2oDCYI_U zLHRh((~#VV;&JSEqi^@m?8UzOrM~-%KDJ?~>C!!OLFmzY{dY5GuAlHg5D$wv#rhQ& zg-d(q9qy{TVL9_sT>HDY3;bGL=WK0krZ)EduB)C`SH8BgSi4cG-B@7v`|o+>)1Wp0 zyHs&!u6C)K!ujfo*H#p3*GskQ3zi#NI&@-g)du?Y+6J~>8Jl-1g=aN*hwAdKS|P1! z<$RROqEU0((HobYLv7A)dWJ%-S6uM@rf;y$^{+bNyH-~*RO!98Wa*H{d)@9v$aRk! zA=fJ@-t{)uP>1*WGCN%0Cf?;%kugmkbd&vNEj%xAJOdxUXei1o2^(uNB_wtrm7WYL z)g&^>Q4A9(Gh>8|jpmN0go$?j2(i9@kw!-Z9|GEFjWV=Q@HOG)n4BQ!ElBrqt{m0? z4)5=a4$}S=_HZb1fDPFrN7zoSTb}*>N%2@te3a7o_V=GW!yfnJ(ZGKZ*@**#aM(Bo zr4dP-KU#iqRi`a!(H$7DJ^t3$pVgD4XlIIwxI%?zrMR z*;>VjnV6&0NI-=cZ=Bfyv1k4`?di)UM^dGr09^q_&=5sHrV~hooFP!Ak@h15l)@0h zVISVHaeyv@VPX{VWZZgcJTIbtHnD-6W;mrvMiTKoQYFv$7>OF7>`Gu%q&8;*jSVod z9r1J2`8qIJ%jql30elM7Ae#ykOY}2<5n#p$FVPhEZ^%i**@enwH=qsokQ9hvYm^k} zn|Hc{p|@fyrP$q4Z0j7Yn{R*tq+kfrKsY|2=oeQ)P^bj3(13!td+!jz_d;A0>zxW= z@rfO}+co3sn$Az>uN*4$Y`OXf9Ne#u6}lfP`u0k`y#?RixoRTr{atf`rBgekK-HdSiu)#(;b_4IbunS zjE@c9>Qm=EWGI;VGz@mr!8S|)qfCFi7&{9X@CI7&RyC8)5U5aI8&9XD4(p`35As5$ zOlTemG!Gm!57?peh-AHRMkmtnOE8^Wi}~gPje?m?db-m}G{f&==?Nk%mO zPu-Yls%PvLYR1LQg&njhs+?dKCYG^QjUH2)H7fT&R2UU-PG~-w%V$q9?ho^zpXP`g zyL(`&q=Yi@<1(ucB8pBp2KGmpGXqG#rc23}q~614)IMe^iEC0&x-p+Gn-Vi(3jcG2GML{CCPX*U>fGv1z7b)9V|5e9zC;6+8Az9s8#OZ-wLo zcW~y;yvyU?ZD)J=hWqt;{#)>E<1^f!CrHeu zcaL#;m#ZwB*~9pNdeH=C^;`)Vz-(J5kBAnSl5zmZ;rR#py+IMW;Mc;_hb&!{9aDa8fWa56h_WzYU&>&=)C#|8lOZ+Mki!E zGo2lwUhj8&D0{(*)!}Y<$l^YXdrHhbHiusHv>pRn}=x2A{I&6hshDU z^iLW}6Prv1Wz-Z}93uk4R!Ei1HE%wdcB#pA9^)5`xv}k&G`rb_GEz<0Wn9$7wq*6R zPweFm7e&VmXO!U}Me)n|AcvnIouWyn-`Z5C-|DFf&i*|O_)|#o zK3JgI#wq_?Wmu{t%PamZ)9a+p4N~V2d$`fqd}*E3(l51aDmHGG8aGevdD|D%_Cmc} zeQC$n8!tCb-;Gs`(bsE#+*I^!mwej`zU?>aT3?5SuY3(P(?9y+WXs$vOcuFEpMj)ul#8 z=or7#sq|U-6*F9LAT^RghYhFLf#8G)8ik)(d*XJd}ovXkEwJY!&{6E zI|9lxu_sWzr6*xgF zq3ps+ZzHz5UVu>FW6B|f9HvOC-4q^1_!mgK-4q@{_!nt0z!YAE@Gl8nmhftXcjNm# z`2IyiT#l_gzm3Q|wV3cn(JRapO=+w`?MqY{9y_T}JBF#611C}&x2)`^mVhL|& z;g4FvmmvIQ;fN(XioWg;{-uyKzcIDhQWo!#{)#YR3GYGpcZH`d;mZ;J8^U=@cnslJ zgl8<_D-iyI@T?`g7vZl8pRt7Z3Ehy<{3Z^##6FE7NMML5q&B{_TBYj`KRgEAjgyD> zXLEy)%pE#%WD)tD`1?q#qd^(*%&-%a;HjhmVgWXB?9>g-Gb-FRB7e z2iGrfg02UP`U(0V6)K{sp7`JynIo zwY>SChT%busgnq^H2Jes<^y;mud%_WTw1yBWE|;N({zk8qys5rD6(<&5L(GxVRoE6 z1Oplf=+`Vz{a32X8l>k^nYW<;4ZBUQdlDXZh+H z3~t>jTld@8tm1~O{^{#pYF0?|k;X(vo{8=6F>>#d3Zd)ZdmFcZQ? zp^Z{#W5KuJ&03}87Eh9jOp9rY_+ zBE6ib(pNf{PNhycfS7Xqh7o__Qe82$L<*TTBJ>IptZuM?B0hzr;%CXxe8igF3MY>a zV=pA}O9zLc9H&kV0=)PrhhEFzF#=y^+rw_O?E$QfQxA_KrFbtAV2-mos$Vq9#cGDJ z;F70x7S62E*CCJ9Pk3tt54A%BG6!z-*&;2|_hIoMyrmf4B85rezx)tKPjbnKu?|`f zE{Z^!6$GO4kqH4yMQKP+Eo1hWb(V93wb*W-?0Ya3*{l)MqDZHxSTg7T|D@a{K zVwl~K)t*v21_^A`IjmCc@E9vqzAAR{tB7eXZmCM{1Clu;j?rf(+RF5R_BujkCbpEY zNaOQQU3f}4PyUvlipy-?{!&F1NuAA7(12Xf6q(O9;cGrh*qd4^9_dd|@oJwxbK%TX zh&3iR>O+c>YT+=^s112LE``U~j+6GX=8nZ5BArNVz4$tO`ng-GlnY75(Iy(ov?IM} zq$1WJJ;TG(kY=Ob`_cQ#&Ngljr`#@nJ|a|00V=Sf(Lh8j8xh^`m}^36pJt;ye6o`1 z9dRp?h!WKXWn-(3TsI>k*C(f#*_dc8Qz`XrE7hzCIdHnQNw%O9ezX{VR0@*?9o`jx zPTwRIY_$ULYh4k=gSi4mfu2k+iKG*z08+}-&>0PK;mu0kCM2tX7^5b5H&rEq?5UI5 zFHLHvCO?6|TiuKDA?i9xsVaFCIxSdS#?8T8$(!c;&2Kexz*}w;`mmlOAu;5$1iyX& z&*$u)b9~OjagpGja!lE$JR?rQ`CQd(^EG!Z6U zMu`8K%cxDP$9x!Ip1piMfU#Nn@_6uoIbgq;hUaTeV|V9iJj>VfCi79GyydVxZ+{-F z*J8&EuEtnC<9O2fxa|yE0|+XdKhNc>5YX~X z0TUbaW1p69nC<`;+|Ojile8kw6bSmaV3H@(xqJHMbZclRokxxkwB4v$_R8U_UB#-6 zQq@LCUW3>j0tZL#Ud-d*p{KBhCkJUS-=P@qs&Ta!CLdGwu_o7IF|hrTJLY`VwbFal zzS4`Sa~drmo}p%t_tj8OL8wSABR)b7ffJFKQQa1PubID9vk@mL%~Nog3U>5~C!*0P zH|tSqTCmNG9L$2zR!~clkP}svmt!LiKbr8i4oHQn*4apGCK4+~dZkD&3=-DCAYsj1 z`@oIb#+PfMlYiw*vGy*h_O5xas~&rz;Jix?41dtZsD&MQ$CQdzP(BSk58(lWo5JKv zqdBJ0O4iFbNA-i&$$Q`rkfs!7WV0fbhN(^yS1yuu_lXw$h&83yN{!iuya3@yC!=xJ zw|vI8yy#mY`BoH^n*(g>&tb$@FY+^FvkD&LEE{DI`Q)O=3#bX^@@l2<5-Hp{y`vCbb!8nK z`IafKf5^JB`SfWts0r8Bs>5Div#7ad4Cd%!++VI@%dgZH!s~I0a(KOb`_^-kvYL?2 z5RoBR)YzXDVJM~iz`b+2@^`4iOvA5KFC*Wh@~0A~*tek6X(jJXaSl?ALaeLa4!0Gl zqlm*{s+tXgY|nZ(F6*6v`mFH%5w$*|+uLy}EFUly!!b>YFkt zeMqTlMO#v;Z_1?f=ZPSduSw6OchWcMH!k~vPO03>58B>|h>T(>Ik9=cFf*u28O3rQ zo`pc3+1jUhSCD=%n1%vY(qYXW!%Vp}Wl-|~P{f7qk|Ucdc}8-lFayZuBGv>k3QN9` zoRAvM3MnA~G?1E4Q?)_||9M+_VkwhbE^zoB4 zQ;AyxVbjuf`R?gMU%&VAy;Bd~2sd5o`@WOY%vjzGuAXb?EJQlrZfJV(sp&1nhE-C- zszQWwxreZ7OEXlPizPR-d(%d^LNF+HWCn( ztCu-Tj{a4=hrdFQm!@`9HVt~KVoMr_)BvuWx@V&A_6?xLCIFu6L{=c|3XzTczT&#r zda?DAP^{{ds!(Y;m_e^ys4De`s17sMUofGj_8mK5PNXTNiAPHTeOK_t`VSO?L9ah1 z9|K_oy`VJ1L@raPrm0!^`bQ0#n#KbbwH2lPAfBKLrhiO{qWmbb2BR59SeRd&o)cff zH;kOPzMPLz>tyjYg;c9``&ZKjbDaZJ9H_r|>=oxL4}br@!jkpH$_-K_ROYMvp&PBy z%MVGd8|EUd7Xz0bEk?SeNEdYB+d^;Ex6C!P(OusRBXDidQzZu)sZH}i_0i^Spcmzx zsohh%->bH@b;zHPI|;pY)eEN>*(gOenm^X^p+7cXZQHWl{^PBMh68`nu>4BHYi-4b zyQGG@3JrJtOqdGHZQK23sL=S>pEUMedGxhU6dSiljav%14?Q*&T=XUFe7wdDgdT4#3tncT$oym zSc@Vl96OcK0E{|ul+yUAgbZ^)GGxwr0^BnId4ag5S4V-o}VDS8J9&eJ&TKz$jV zdm%XM>zVQO{K@ir-tZQE_es9{3d+qX4A=22pe2K&E+Se=LB`J|l7fI;DY;v9d-l_D z$b)#)Z50#ysjaDfm5U(Ovy5%W8<}vx=A+X#F;Jcz7^^gdqlNi(&ZTdAP1|Z(iD38z zgO2ZMMl7(+$UUtumm1sfH7YH;451z+RB#yCd?*z=#TMkO)6!Dnf($U7C9Ee-m>RQt zng}b)MIvSMRsmz$vH!ols}GLry6W%kuH=<=^|e~9t=N`ieOa<)#g_b;*pB7+BWi3p zw&gTw2&!T!iECLhS5n*rr=zqkD4h(W83K5K7G-FPlD31GB;YbIaS9zWErqw@fgVd; zRAy5CVVG4SI*b??e!qL)d;8wLb%;~wUp!qOzrE+)`|iiNU+124ZWBb06S;^mHJn0T ziVCYC_!l<3D8dmJnji<+e)3hUup9{Yt?KuPuOI-#{(DfLnP|_kf!@BO{kt=3>^DW{ zoUp|t!7~gNdE&z85ErQs(LX<-^rc#fC3#?5Eyw1saBTh^0`34Ye-B=|F!HQeiy#5* zsFc^pOc4I-|Q#Iwk)y(x}rEp2l@Yhl=*U!|y_3)cN54B%hqH=LD z)wYmon@gor+s)MW>6jI*UX0c)MC-o%j9I_qt=(q#(VM@Jj`o_-UL)FT#nyp+P|{^3 zHZCR_7ZQ!L2hxchW@3jCFW|C~2<}B;(3XV+g!||EXGhYBZZpws#0xvfKtYGlx!**- zS@E@t@r?`djp=y38Lv0u^|;~$7q!UiO~~=za2@x%wJ9sOlB4nMH5(7NXy0yWxW6dO z8)qh-UX7s#V~H=9JF7`~jxDM0d`?qZXC=%d*A_L00Rql6Bcr;p<-DAy>WmK0AqXRV3f zBc(1Q*GhTxC@I-K*m<2ONw+K*76)pV&P65Ze_(R-!e{*}1TW^-Nw(NsIfuA8`ut|< z8+GZ_UNg0KI))2?yi_&xA-1<+jr-$JRKsk{W$((fgKw_yDbe03Y3OMOL5*Xu7n@M% zRk?RoM05fxMyfUV$cS}-fBFXvc=7KL@|)PHa9uo&lwY&Y0_Rbkz6sGeAwwUBi4yh6 zf+u9&0I#rGE0G1Vt{Y~P>55jfqSc7D%K7c5&++rfv3Mgtt4Vvq&nD01)yKXl6yjBH zW;e|?`!DGfbNI|^l1(r?(a9+nGw?AvTxOtpdT9)&hxWXjDHX$$*-^!yYuvuDA%2Le*eZl*ZpzYg1qO}NSKEsVk>55vDm9QPr>;WYe2RwB+nr~qh?w( zAfl-0w)E_&`yU)Qa{NrsNg=1$(`cMb{OqZLGe^&zJ^Ik8GyQ_~s|KeTQsfH&&J4?> z<>V@E@aXzAy>FO@Cy32@ny;r^A`eW(pb`$zbaith1F0g82c5jl? zXUdr|j|@%>J|zY(sX@=DEQ3gDc}s~RdwJ`~!pTkdYxW$$~PivcKcB z!DjCo|3d=4&DP+&<}Q31TV|`}IJa6akJsG3AGqQD&PpTxEWZSTw;?_EQFHp8Ku))I z&NZo=COoSZn=!e%w{Q~xeJ91@Sn~zWNEF=r(6J3=2|oF=78Dpm7%#$w$FL6{X}k={ z{QUvO3zvl#+&wsRr83|o#|LqVL?ss{ukh`+0l-_4t816uRF6l!YYljmD$pIZ+4tCH z)WWd)derXgI~P(r=RcKB9Wqmg*vC`sj@`NLcrl&mG861>L3gXVbM6<@)%Tj!)cSkR z*EuCMC}m^Zpo|s~e*z%&LSPl_QIv5tA(ynE0!1=3X}(&i-W7ja`c$iT-+U?4TCG$V z)t?{4UPXMD-;rrgx(sw>Wy}}7qahckqXDUOFbf?GDyV#gC;94rA3LlMCu7TkJpOo2 z(~u3tWv-;xPvPa`(5qsMUoE;?{58ymUw3Cj@2uz0Q`j@##9$1C3yBN3D6QQ--OO#% z+_uQomO9-eVL7CgMn(E}Xr43|NlFwxu}P^_!(#Wb#hQ+VnvS{t`JFdXHH{~v#p9|!edW-X0_sh z!SQ1kMutbnK$W05-^$mmn}2odro_j6&ma4|Wmo(za3W9$=gF=7utDp9{+hd93+S(L zR1Q2>LpgrGf9uHWF{x?yxzH8gAye+S2w$v%?wV%|%~#oG8V>J+B6>SGU>1ueWJC3W z9eB%>U%4>x^uUB;2?@74=YGIc8P9s1S^e+WtiKBnf3q?{zXUiqt?_!CQ&?*>F11Y$mAAe>=xZRm}={MNdCeDfJQu-b%Ej6PwM%=EcPBg~aap zadXcD=|r!Y=zVv>h@XX|fQrg1I7(=G(gwE@O|yN9J8>gv#1Bw=`XB;JGbPt*)@#32 z(X%uB`sSXh@HRC!QNlDNpDsl{&1lIS`G~(KO=Jj2DdHdS=BEyZFF+kvgtEHw zA3^Ha|FfhHmG!!)UhAbA%1{D`HltI&C#Lt4}OdnYBPEnsD=4O zUqi^RHG$%(PCi<6g?CM9M2Bw=JqCdO*MLRV7AuWy260B|M70V=4j{AV#G|TncabjMKncJ_O}3z%@JslUnf!2#|Er)(PraypPX1{gm&%5uF}> zaj?RvZe>GIn?$V{m!f+NzgsGAHp-jR<*jBpx!kvNYIiN|X0SG#2dS%mdlz2({dS0k zZFEXkfu_#`jVo#y-zk#R=VV&WxktigRk8fGnJ(C<^N7?0@jF<$6w)BGzE&xBUO(LIeuFf zRtgx)tZ-={K1+}*tZlOalJktHlnPmwKU)b_ISBiQo`;nrXdApfTTH;+qt| zk#AD`M!v~LS?5;SKjZDSNKP6fSJBGqVN^&i1EmeriSP%E%41>i3V|%5JUfnv*Xh9n z1?BqG$X>&%XbXZ<4dZtE?q^O8gbyzDpqMfov)JjhXptAkYN? zncW2j>yerC2m2ca!_}L_FA~U1us9C!N?MEL7Go;JKQW%&>RiY;?>|=Q<#jSS5Nyjc zzJYm-3c2=O^8Nhy!vxeZ7LO5}WL|F)P`Obm`*H8Ci3Gtg{is1EK0|PcV2pr;7GyVw z=Lsm>Ej~|hjo_CFeuLo41g{bNKEay=e@O5)0j0eq+ghaglROy30%#`UNBqf!pm>iU zOYlCyzYz>E$fpSg2u{LAY4p_#$5>?k8Q@#nj^I8ed zH5M+OzPNTm;;9_$C)mGd4vEc<^;D-gEba2QP2tl?{o1U%i|t=gTya2wtltk#;$BQ%o{9%z>Ppusa;?Q#_2^0xOjRv6@s0LUZj8r zzuv`T*`XIH;K8qT@p<=n$OhrX9x{E;t*VcJ!Lp{P5OkB3Xs03bE)cQP-R7j*)Mj;d zWn-1Rl*0$y)acu6SHe~nLID>~4^;`ptRDxsczRUI_{D5c2YB$iZM^Qa7w_WftI}^R zI)TFHpc_PbJ*3;2>?I4T$boJk>BWSWKGByASJ0G>54Zv8+bGkD^7<7AxOjRb?QfCi z#p`DQTs%EghJ9D3c<^mDzM9s^9N^;Vu?6W{MP=Dgh&|N-3{rmW5hrAX{?S}WT#Xyz z{kQHS}Dl`Rc-wWWu@3-+$b~OjMczURo3G>n#2e^28sPBh( zzpn#aJUv*S*-&{A*bfeH@$_hr_%IvY0WO{%&Um426((i0xOnHTVd<;JYdKW^1VeTE zOr~@I_7Q1b8|+-}3dIRdJ8}a06^`gV_zBVXXUCxlN3;0iIDDaOG&V9q16sIzpcChh zBEqO#Ig4Tf?tKN%ZUklc1y6(pnbDa9#C`0oc&GaAxS;NErW6QrJw`4(A$We9iSYI~I>ZjpAFCNpHs%o-&kJ$4K=A4FsDA8VQ;RngKE~8I5N& zFs|Q1?{%!va_Q}|!lX`JMw6GHiFStCLcm3b=pfhzkf|JiG4LacR0=29=%oOe?zMN;?o_aV!%u$H}4-HpLjCWpwFpzjw9HVE+fTUem2p7lsJO0eD z7zgc29)kD;y{Z(IK)M)A2ja%X3HXbXM3%euRir|^=p*J70k;rRG+3PG+Zlqh1m6P4 z6rY(KeRxnPMf*4CQ*{^$7xpbrXJt;s_vv3w|Fd9s*q%RR8r&;nN_$69q{&OH))Mwj z+FBGpAfBSrly+6Zq=IsInR0b1>xiRCX)+-Nv|eDq83G=Ti&qFFx0ZZBWfD`Gg5&6r zDWjQdWJlSP$y@8KM)zMD8=4#$J}BxiW+1vYeh7UWJaJvOv_>P~mbCbk{Ij&!l>D=_ zk}3ITX=PLL&(cb#h->;T zL)++-svwiNm4S=wI1@36>XDQ*XfH61bbc%7x8ZhS5q z3NwxW8ALVxkZx%Ad7Y*0GyKldjvKdk!SE`&rJ=Asw-m0#T0?KPB29+hErpBCaP`cU zg>an_uCpQyM!+pawi^2IyrATb*`1JiRoVa#kO1EN(={+;| zq+@lkgE|$p%97KcocX!g?z!@G*&efO&s3=uTRXk~dTBb=WX75hB2qThJAM9zzH5C` zdbV6EEq`gFS+a4eI9u7NV}%w3Gj}i3cO{1!(Ytlt>sT1hgkLUOmbevfh-dV5I(AG! zFmu+d*}P1|N)CGnOx)O1?ewsrC)0Y;)RWmzl@8u>5M1vz*Kc1YVub)p$54$MzAczc zoXG^i^{}~a%Q6uw1i54wv@V#;E`38*3xetMFI`-w{|Z4a6^6X5hZrdcX8XVTh}p6i z$8wD4;!Cwd`Z4{+GghQyIUG8qhkye#wAQ@7$B3b9X(=1f51KdVsjLXBPP^1ZS=?(!OPhUhxJx7An)Rn+yVD zUE5rfxn=({aVxn14RIYC%OEgn+vmE?tq0g}+t_e+sJdz$H+TktQQ0tCXI5^XZ+dgv zGVv?9KphFj2?Bnj)2!Whquadq^fCjiwYh{AKjy!?GtAf-|xo zAJ*BAUHpjNt226GXr$VgC2GYR0Q|!4eeDYx9hBF;V U9C#$23pH8_LmX-aD0ip-4OLj7YXATM literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py b/venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py new file mode 100644 index 0000000..ed91f40 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py @@ -0,0 +1,2816 @@ +from __future__ import annotations + +import array +import asyncio +import concurrent.futures +import contextvars +import math +import os +import socket +import sys +import threading +import weakref +from asyncio import ( + AbstractEventLoop, + CancelledError, + all_tasks, + create_task, + current_task, + get_running_loop, + sleep, +) +from asyncio.base_events import _run_until_complete_cb # type: ignore[attr-defined] +from collections import OrderedDict, deque +from collections.abc import ( + AsyncGenerator, + AsyncIterator, + Awaitable, + Callable, + Collection, + Coroutine, + Iterable, + Sequence, +) +from concurrent.futures import Future +from contextlib import AbstractContextManager, suppress +from contextvars import Context, copy_context +from dataclasses import dataclass +from functools import partial, wraps +from inspect import ( + CORO_RUNNING, + CORO_SUSPENDED, + getcoroutinestate, + iscoroutine, +) +from io import IOBase +from os import PathLike +from queue import Queue +from signal import Signals +from socket import AddressFamily, SocketKind +from threading import Thread +from types import CodeType, TracebackType +from typing import ( + IO, + TYPE_CHECKING, + Any, + Optional, + TypeVar, + cast, +) +from weakref import WeakKeyDictionary + +import sniffio + +from .. import ( + CapacityLimiterStatistics, + EventStatistics, + LockStatistics, + TaskInfo, + abc, +) +from .._core._eventloop import claim_worker_thread, threadlocals +from .._core._exceptions import ( + BrokenResourceError, + BusyResourceError, + ClosedResourceError, + EndOfStream, + WouldBlock, + iterate_exceptions, +) +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 ( + AsyncBackend, + IPSockAddrType, + SocketListener, + UDPPacketType, + UNIXDatagramPacketType, +) +from ..abc._eventloop import StrOrBytesPath +from ..lowlevel import RunVar +from ..streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream + +if TYPE_CHECKING: + from _typeshed import FileDescriptorLike +else: + FileDescriptorLike = object + +if sys.version_info >= (3, 10): + from typing import ParamSpec +else: + from typing_extensions import ParamSpec + +if sys.version_info >= (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], + exc_val: BaseException, + exc_tb: TracebackType, + ) -> None: + self.close() + + def close(self) -> None: + """Shutdown and close event loop.""" + if self._state is not _State.INITIALIZED: + return + try: + loop = self._loop + _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() + 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 by 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._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 + cannot_swallow_exc_val = False + if exc_val is not None: + for exc in iterate_exceptions(exc_val): + if isinstance(exc, CancelledError) and is_anyio_cancellation( + exc + ): + self._cancelled_caught = True + else: + cannot_swallow_exc_val = True + + return self._cancelled_caught and not cannot_swallow_exc_val + 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() + 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(f"Cancelled by cancel scope {id(origin):x}") + 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) -> None: + if not self._cancel_called: + if self._timeout_handle: + self._timeout_handle.cancel() + self._timeout_handle = None + + self._cancel_called = True + 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 | None: + 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: + 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) + 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[Optional[T_Retval], Optional[BaseException]] + + +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") + + +class BlockingPortal(abc.BlockingPortal): + def __new__(cls) -> BlockingPortal: + return object.__new__(cls) + + def __init__(self) -> None: + super().__init__() + self._loop = get_running_loop() + + 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: + AsyncIOBackend.run_sync_from_thread( + partial(self._task_group.start_soon, name=name), + (self._call_func, func, args, kwargs, future), + self._loop, + ) + + +# +# 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 + + async def send(self, item: bytes) -> None: + self._stream.write(item) + await self._stream.drain() + + async def aclose(self) -> None: + 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 + 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: + if process.returncode is 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: + 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 = BrokenResourceError() + self.exception.__cause__ = 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 self._protocol.exception from None + 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 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: + if not self._transport.is_closing(): + self._closed = True + 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: + if not self._transport.is_closing(): + self._closed = True + 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: + if not self._transport.is_closing(): + self._closed = True + 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.Event]] = RunVar("read_events") +_write_events: RunVar[dict[int, asyncio.Event]] = 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 < 1: + raise ValueError("total_tokens must be >= 1") + + 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 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) + 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 + + # 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 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: + import uvloop + + loop_factory = uvloop.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): + import uvloop + + loop_factory = uvloop.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(sniffio.current_async_library_cvar.set, 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(scope: CancelScope) -> T_Retval: + __tracebackhide__ = True + 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: + scope._tasks.discard(task) + + loop = cast(AbstractEventLoop, token) + context = copy_context() + context.run(sniffio.current_async_library_cvar.set, "asyncio") + wrapper = task_wrapper(threadlocals.current_cancel_scope) + f: concurrent.futures.Future[T_Retval] = context.run( + asyncio.run_coroutine_threadsafe, wrapper, 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: + sniffio.current_async_library_cvar.set("asyncio") + f.set_result(func(*args)) + except BaseException as exc: + f.set_exception(exc) + if not isinstance(exc, Exception): + raise + + f: concurrent.futures.Future[T_Retval] = Future() + loop = cast(AbstractEventLoop, token) + loop.call_soon_threadsafe(wrapper) + return f.result() + + @classmethod + def create_blocking_portal(cls) -> abc.BlockingPortal: + return BlockingPortal() + + @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: + await cls.checkpoint() + try: + read_events = _read_events.get() + except LookupError: + read_events = {} + _read_events.set(read_events) + + if not isinstance(obj, int): + obj = obj.fileno() + + if read_events.get(obj): + raise BusyResourceError("reading from") + + loop = get_running_loop() + event = asyncio.Event() + try: + loop.add_reader(obj, event.set) + except NotImplementedError: + from anyio._core._asyncio_selector_thread import get_selector + + selector = get_selector() + selector.add_reader(obj, event.set) + remove_reader = selector.remove_reader + else: + remove_reader = loop.remove_reader + + read_events[obj] = event + try: + await event.wait() + finally: + remove_reader(obj) + del read_events[obj] + + @classmethod + async def wait_writable(cls, obj: FileDescriptorLike) -> None: + await cls.checkpoint() + try: + write_events = _write_events.get() + except LookupError: + write_events = {} + _write_events.set(write_events) + + if not isinstance(obj, int): + obj = obj.fileno() + + if write_events.get(obj): + raise BusyResourceError("writing to") + + loop = get_running_loop() + event = asyncio.Event() + try: + loop.add_writer(obj, event.set) + except NotImplementedError: + from anyio._core._asyncio_selector_thread import get_selector + + selector = get_selector() + selector.add_writer(obj, event.set) + remove_writer = selector.remove_writer + else: + remove_writer = loop.remove_writer + + write_events[obj] = event + try: + await event.wait() + finally: + del write_events[obj] + remove_writer(obj) + + @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.11/site-packages/anyio/_backends/_trio.py b/venv/lib/python3.11/site-packages/anyio/_backends/_trio.py new file mode 100644 index 0000000..b80cc04 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_backends/_trio.py @@ -0,0 +1,1334 @@ +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 concurrent.futures import Future +from contextlib import AbstractContextManager +from dataclasses import dataclass +from functools import partial +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, + 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, + wait_readable, + wait_writable, +) +from trio.socket import SocketType as TrioSocketType +from trio.to_thread import run_sync + +from .. import ( + CapacityLimiterStatistics, + EventStatistics, + LockStatistics, + 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 HasFileno + +if sys.version_info >= (3, 10): + from typing import ParamSpec +else: + from typing_extensions import ParamSpec + +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) -> None: + self.__original.cancel() + + @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) + + +# +# Threads +# + + +class BlockingPortal(abc.BlockingPortal): + def __new__(cls) -> BlockingPortal: + return object.__new__(cls) + + def __init__(self) -> None: + super().__init__() + self._token = trio.lowlevel.current_trio_token() + + 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: + trio.from_thread.run_sync( + partial(self._task_group.start_soon, name=name), + self._call_func, + func, + args, + kwargs, + future, + trio_token=self._token, + ) + + +# +# 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 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: + return trio.from_thread.run(func, *args) + + @classmethod + def run_sync_from_thread( + cls, + func: Callable[[Unpack[PosArgsT]], T_Retval], + args: tuple[Unpack[PosArgsT]], + token: object, + ) -> T_Retval: + return trio.from_thread.run_sync(func, *args) + + @classmethod + def create_blocking_portal(cls) -> abc.BlockingPortal: + return BlockingPortal() + + @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: HasFileno | int) -> 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: HasFileno | int) -> 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 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.11/site-packages/anyio/_core/__init__.py b/venv/lib/python3.11/site-packages/anyio/_core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbcd8dbbb61b1e8b89082aae5c2859a8109c48ee GIT binary patch literal 190 zcmZ3^%ge<81aZ$^r-SInAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnuR#5>#3KFj z@^byu-2AM})Uy1X(vr;lJpHoNyfXcq%q0DS%94!yJYzjWL;d2+l2qM-#N_P6^weVg z#JtMPeEs<3{GwF-`1s7c%#!$cy@JYL95%W6DWy57c15f}8$fO-<_8iVm>C%vKQO?E IB4(f%0AQdo6#xJL literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_asyncio_selector_thread.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_asyncio_selector_thread.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e615cd2f53fa928e1d6bb3f454bfa0d3e02cccf9 GIT binary patch literal 9088 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 E0XuWn+W-In literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_exceptions.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_exceptions.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b05aaa30b77fd1897b3ba2feeffbf37fb212cd0b GIT binary patch literal 7195 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 C`9GTg literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_resources.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_resources.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f878b28fc15bcd008e558b4adad918c4ccc11c73 GIT binary patch literal 1114 zcmZ`&&ubGw6rR~1X-vD(itVj*Q9SIyE>*k~5lX!YJs1$0gUfVxny%fF6Hc8unnH?T)-uJy9`7-m~vI+>+qaVL2 zpD;q-)uFevj)RYGg0qbR6yOL|aT#M2Xn`JSRlTf(Zv^%LUgakMYqv&yoz_u;inMlXJWL9cDf>*ag^83 zTLWR9=?~Gi{>lIeu=;i(Z|^i$MN8-!nnu!SXixM7)Bq6|VA2laXiq;DY*=#>1L7T@4sij!Z9lLz_#?6wJ6S!!l}t0I4tIg1VSj*pKAVi_PuVazw~tflW; z#_Z_O{uK;%-Z3%_vpX*?07a-5>I|g?&s$311yIiuI)qZ4Ec)H2;l)I*$m~DKWcYxN zfPutCFemvtRURY}y(`Ays4l)-0Mphn#w~R9pnrculL!5~)qe!Eog2oW!2l!1p!z>f C92C<4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_signals.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_signals.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c60952015c293390fa8a4d25c4269eca9097d80 GIT binary patch literal 1359 zcmZ`(L5mYH6wb8WcDJ?4g6u&>9-b_?Gl-swyRdkW6;z~xP|;~R6WeGe8IrWMpyI)c z7q9*UMZEY^Dkv;H34$PA3VYj=FEi7HqK1&ZBrorM-#72|L$g^YI3E4{J$O?lq@sCpXiX*$zLvT%bPc-l*&@el{C0*?wP5K_AS%YDvbwQdwpXyjqG(LEqi8fQAr2P z-PAgKAgM6Fygbt8fZ33`=V6~lPnnG8HIuvOD!R<8n%R+-NB+MzMu#aiI16>f>FRNa07j2tm8(aKK_oZ?EtD9Fo-=8&hW|f^o zye79>l?+qXS=v3*4P07{c|8mtkFd{J7;4uo^HY%$f<;+}`?MeFiaV_rrH6R+nmefG z!sM-54;iwtPP9yy4BSVePobwiiObRYwM4}u!FKf)Zk;mb1ul!S=XnR@!fbVZC#~7) cJRsY%)pxvjpk;0 zzyJ5`E_MM@mYpTs>4B zt{JMqJC{@(stwl-)v^1MP<^;zs3F`q)EI6WY6`CzS`%J7v^KnMXkAzw62t3<)`y#i znps+Rs3qJw)XMHXp|q3#uU|R z3M#24)D_+{vF2(pxuwz z>a|;8=s}ie<#bjEQavwqt(t1jHLLW3w72lRWR>p2e>eX3N%voKN?(y4e8D;Nu=MNF{uk^+J%|@% z`x&p+h1}Rl2axk1TKA%K6gl=IY0^J;Q4@YoX0Fw4$^<&noYVa4ZKh^bkO)- zeLIK|c}aR4xqA^~m7YLpUzMK0^CA8DiZqPpM^GC78$q7mkj^6Ru=JbK*QDqRj-fux z{~l@b4GYE||NN5Xr1%T=y!kl7Qce}5JXetNsPwXQ5hHR8-6@yc}~5T7^}JS%4%qZ8q%gs4(A<)J`07`m7(8HkRamE%W)5y|h!mJU93qIdYf z;obvB`;I@7we>_UW{ZvmSCDy{Uk zl)o*J&(|>8)c7t1F&$Dsp^Ei6~8o8>OX2mjnMaOV8u$XM{hG;*k*Kfbgc}_?yC; zMaovhD%&WaCbGsTRI9R^0;(ZK=vCy`oiA)X7f`mIKYxBJ`g|rRpNod3Xa=@oX3uR6 z1y66CycnN|Ms{{?-@Y}5ov>vRYa%c%$F>F{7lYBQ7*0jrIviu$DAqZN;lr@g9vF^~ zPAU(guD$sG8O`E9;BQ7)t`f?t=4?Mhgy6UHW|~`gr_4NhcS

  • JZ+`SSZ~nS|Plo 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%0D##49UVgxTp;*dX-%t2 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 W;>-zf|2YT#N)SMtd|Jqv;eP=*`pQ)R literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_synchronization.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_synchronization.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8dcd677a48d22903683893dc01dab170cb58fbcf GIT binary patch literal 35713 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_tasks.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_tasks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6520edce4a182d1ec22d793be823ea3e42d652fb GIT binary patch literal 7700 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_testing.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_testing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9e40e45245a28867e22c0827577cf389f761729 GIT binary patch literal 3870 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 a%QlIEiInyZWXfG|BBs6GCeH!V0{;Wkl#f9G literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_typedattr.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/_core/__pycache__/_typedattr.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f07c3962ade4bc658e7031943e3ee2174f2849e2 GIT binary patch literal 4412 zcmb7HO>Er86&`ZAzgqpSE!jz7GnK7)V|&*>b?ORjQ`e4c!#@rDQ#5P13`LGC+FWuo z0tN&W4G{FQhFm}}dgyyIT&^e^ zX*-&I8qPevdGp@9?>+vpw>L+i{qpO7-uhdXkiX+Yrzv6}ZTtlW4~a=k$tG2)B1t%w zZMmALB&te9;m-*>Sxr?^)pR9Y%~UegY$XfxikY-?)t*X^L}WtKX6ms-$P@U9R>||( z^tRbvnC*KEEKfR&q|$E=n7L)8G9Z()#OzrnX8y4Z9PksZGRRkYVWn@|%8=QAl@tfR zLB^sK^yrS``nqqqj#rd}%xT@W^+}rs=}UU8W;wTtN{~3^%m?Xf^ELW&odwA$%hBy1 zerdW zQt+~Yx^xjAPv z{?Rjd|K!TarJu1Oc#fF?On^<=*a!62U?);;h89$D>PsuGvS`rs6Sa@lpLvBjYTy$>gqHok_zZ=|@p z7a_i}Ip0Be8;?j+ls< zSd@P+o60ANIQKnirR)PNbXxo}K1z1xxBidwAT)rVl9z*iP3v07)3iX+7IGLNJaW{9 zy{hG@Rm<}r{#45cN5qW^zE0nw5Va6f3DaUh&hvHVd$X254M7IXBJPqNIzAZGG|RDk zt>Y<8!=N^7kD)Dt49aozDh;xl#$Bmt9s(ZRoF!I(0aJl2jJ|ZeN-qiC4UFD>Ae&3% z>Db{-FEB{$1t|nKn_fL!30uwF<9)RT%rSF!sn>EgW1c z9Bh+B@6hL&FM66sE8~qg(L#mj(c{2to=oPrw(ngA##=@YJ^z$&yu?PY26yyb--4Mq7X{v7D9rZK9 zR2Zr)5*FtMsAtrxxsC||8VQ}z?Ka0z4!tIuN&fyL~BIYX{K~;TT#k|eH zOSlk;?4C8;opNn4ZCVb1i(}AYm>ck9Y!FNfNmTKuJ;lR7jg?5Rq zcI-IJdiW|D7IkFDfPA}#-^X_{KtRJQ*PBm9+E8N&D$^% zZBatZ7VU1rIXFuEEhgSa*dB>2%09{nTOGEDWlSlaDNXqvNOe^hs1WI5C)h^nM^C*e7Ru5EZbrJ#(&_P$nIeLwM@KOBAKza2+5pW`kAymtTsuydlXfoU> zJc`&yD9np15!o2bQSe$*s^f--f-+#rh2x8|ZA-l3UXi-p&6sX^0J9(QlC%`pcS}J& zuEHj0I*;nim{zBB%f^@DkN-Im#zC5A00G?ClgjRG?cBY#^Q}*Ru(tC= zW1=y!`Luro3yr;9(&``nq}c2qh5mH7+&uE`>hQ$c@WfxwGzZ>WAKCMu5C7U(cxQ8S zvz;dc!;P8yb1QR=eh(4oUhe>Tu>WM@PtwW6fWzK-!L)^SwKv3)qPAITUJM9LroSp`yqKhF)#5I8w(Fa!m55(#3ofCUaJ zZ{Z^n6z8n~S&IHz%B7}qX+7E7mUBrct2*Raf~5MEe<5af!MLTIX!0Jez%#tnQm!|7 zk7lp0Cv&a0-)WQKN9P!!dRY>E~s7O+H{s>8P;lxU(}?ce&nqE8x3 z0Y-)ec#!hv@tc)@RWbx{VGguT(4)~ggVy+G4!?uKB?#smGKJCb3yoJ>+*I3a_#*Q| zQ7!(My#ss*@!r3Iv=fpfwa9my@xD$DH(%9TuQr8Sm@afyT&#U8~vG*0QfH zrCRwy>hyt}aPumlc! OnLNX}=dW1cj{6U%(P;7j literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/_asyncio_selector_thread.py b/venv/lib/python3.11/site-packages/anyio/_core/_asyncio_selector_thread.py new file mode 100644 index 0000000..9f35bae --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_asyncio_selector_thread.py @@ -0,0 +1,167 @@ +from __future__ import annotations + +import asyncio +import socket +import threading +from collections.abc import Callable +from selectors import EVENT_READ, EVENT_WRITE, DefaultSelector +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from _typeshed import FileDescriptorLike + +_selector_lock = threading.Lock() +_selector: Selector | None = None + + +class Selector: + def __init__(self) -> 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.11/site-packages/anyio/_core/_eventloop.py b/venv/lib/python3.11/site-packages/anyio/_core/_eventloop.py new file mode 100644 index 0000000..6dcb458 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_eventloop.py @@ -0,0 +1,166 @@ +from __future__ import annotations + +import math +import sys +import threading +from collections.abc import Awaitable, Callable, Generator +from contextlib import contextmanager +from importlib import import_module +from typing import TYPE_CHECKING, Any, TypeVar + +import sniffio + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +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 + + """ + try: + asynclib_name = sniffio.current_async_library() + except sniffio.AsyncLibraryNotFoundError: + pass + else: + 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 sniffio.current_async_library_cvar.get(None) is None: + # Since we're in control of the event loop, we can cache the name of the async + # library + token = sniffio.current_async_library_cvar.set(backend) + + try: + backend_options = backend_options or {} + return async_backend.run(func, args, {}, backend_options) + finally: + if token: + sniffio.current_async_library_cvar.reset(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) + + """ + 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_cancelled_exc_class() -> type[BaseException]: + """Return the current async library's cancellation exception class.""" + return get_async_backend().cancelled_exception_class() + + +# +# Private API +# + + +@contextmanager +def claim_worker_thread( + backend_class: type[AsyncBackend], token: object +) -> Generator[Any, None, None]: + threadlocals.current_async_backend = backend_class + threadlocals.current_token = token + try: + yield + finally: + del threadlocals.current_async_backend + del threadlocals.current_token + + +def get_async_backend(asynclib_name: str | None = None) -> type[AsyncBackend]: + if asynclib_name is None: + asynclib_name = sniffio.current_async_library() + + # 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 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/_exceptions.py b/venv/lib/python3.11/site-packages/anyio/_core/_exceptions.py new file mode 100644 index 0000000..16b9448 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_exceptions.py @@ -0,0 +1,126 @@ +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 BrokenWorkerIntepreter(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 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.""" + + +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 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/_fileio.py b/venv/lib/python3.11/site-packages/anyio/_core/_fileio.py new file mode 100644 index 0000000..a0d6198 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_fileio.py @@ -0,0 +1,742 @@ +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__() + + 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, + dirs_exist_ok: bool = False, + preserve_metadata: bool = False, + ) -> Path: + func = partial( + self._path.copy, + follow_symlinks=follow_symlinks, + dirs_exist_ok=dirs_exist_ok, + preserve_metadata=preserve_metadata, + ) + return Path(await to_thread.run_sync(func, target)) + + async def copy_into( + self, + target_dir: str | os.PathLike[str], + *, + follow_symlinks: bool = True, + dirs_exist_ok: bool = False, + preserve_metadata: bool = False, + ) -> Path: + func = partial( + self._path.copy_into, + follow_symlinks=follow_symlinks, + dirs_exist_ok=dirs_exist_ok, + preserve_metadata=preserve_metadata, + ) + return Path(await to_thread.run_sync(func, 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) + ) + + def glob(self, pattern: str) -> AsyncIterator[Path]: + gen = self._path.glob(pattern) + 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 + ) + + 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: + return Path(self._path.relative_to(*other, 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)) + + def rglob(self, pattern: str) -> AsyncIterator[Path]: + gen = self._path.rglob(pattern) + 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: + # Path.write_text() does not support the "newline" parameter before Python 3.10 + def sync_write_text() -> int: + with self._path.open( + "w", encoding=encoding, errors=errors, newline=newline + ) as fp: + return fp.write(data) + + return await to_thread.run_sync(sync_write_text) + + +PathLike.register(Path) diff --git a/venv/lib/python3.11/site-packages/anyio/_core/_resources.py b/venv/lib/python3.11/site-packages/anyio/_core/_resources.py new file mode 100644 index 0000000..b9a5344 --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio/_core/_signals.py b/venv/lib/python3.11/site-packages/anyio/_core/_signals.py new file mode 100644 index 0000000..f3451d3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_signals.py @@ -0,0 +1,27 @@ +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 + + .. 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.11/site-packages/anyio/_core/_sockets.py b/venv/lib/python3.11/site-packages/anyio/_core/_sockets.py new file mode 100644 index 0000000..054bcdd --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_sockets.py @@ -0,0 +1,792 @@ +from __future__ import annotations + +import errno +import os +import socket +import ssl +import stat +import sys +from collections.abc import Awaitable +from ipaddress import IPv6Address, ip_address +from os import PathLike, chmod +from socket import AddressFamily, SocketKind +from typing import TYPE_CHECKING, Any, Literal, cast, overload + +from .. import to_thread +from ..abc import ( + ConnectedUDPSocket, + ConnectedUNIXDatagramSocket, + IPAddressType, + IPSockAddrType, + SocketListener, + SocketStream, + UDPSocket, + UNIXDatagramSocket, + UNIXSocketStream, +) +from ..streams.stapled import MultiListener +from ..streams.tls import 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, 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 OSError: if the connection attempt 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, *rest, 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 i, (af, addr) in enumerate(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 + + """ + 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 list of listener objects + + """ + asynclib = get_async_backend() + backlog = min(backlog, 65536) + local_host = str(local_host) if local_host is not None else None + gai_res = await getaddrinfo( + local_host, + local_port, + family=family, + type=socket.SocketKind.SOCK_STREAM if sys.platform == "win32" else 0, + flags=socket.AI_PASSIVE | socket.AI_ADDRCONFIG, + ) + listeners: list[SocketListener] = [] + try: + # The set() is here to work around a glibc bug: + # https://sourceware.org/bugzilla/show_bug.cgi?id=14969 + sockaddr: tuple[str, int] | tuple[str, int, int, int] + for fam, kind, *_, sockaddr in sorted(set(gai_res)): + # Workaround for an 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 + if sys.platform != "win32" and kind is not SocketKind.SOCK_STREAM: + continue + + raw_socket = socket.socket(fam) + raw_socket.setblocking(False) + + # For Windows, enable exclusive address use. For others, enable address + # reuse. + if sys.platform == "win32": + raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) + else: + raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + if reuse_port: + raw_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + + # If only IPv6 was requested, disable dual stack operation + if fam == socket.AF_INET6: + raw_socket.setsockopt(IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) + + # Workaround for #554 + if "%" in sockaddr[0]: + addr, scope_id = sockaddr[0].split("%", 1) + sockaddr = (addr, sockaddr[1], 0, int(scope_id)) + + raw_socket.bind(sockaddr) + raw_socket.listen(backlog) + listener = asynclib.create_tcp_listener(raw_socket) + listeners.append(listener) + except BaseException: + for listener in listeners: + await listener.aclose() + + raise + + return MultiListener(listeners) + + +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) + + .. 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 + + """ + 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 + + """ + 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 + + """ + 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 + + .. 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) + + +# +# 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 diff --git a/venv/lib/python3.11/site-packages/anyio/_core/_streams.py b/venv/lib/python3.11/site-packages/anyio/_core/_streams.py new file mode 100644 index 0000000..6a9814e --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio/_core/_subprocesses.py b/venv/lib/python3.11/site-packages/anyio/_core/_subprocesses.py new file mode 100644 index 0000000..36d9b30 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_subprocesses.py @@ -0,0 +1,202 @@ +from __future__ import annotations + +import sys +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, Union, cast + +from ..abc import Process +from ._eventloop import get_async_backend +from ._tasks import create_task_group + +if sys.version_info >= (3, 10): + from typing import TypeAlias +else: + from typing_extensions import TypeAlias + +StrOrBytesPath: TypeAlias = Union[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.11/site-packages/anyio/_core/_synchronization.py b/venv/lib/python3.11/site-packages/anyio/_core/_synchronization.py new file mode 100644 index 0000000..a633132 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_synchronization.py @@ -0,0 +1,732 @@ +from __future__ import annotations + +import math +from collections import deque +from dataclasses import dataclass +from types import TracebackType + +from sniffio import AsyncLibraryNotFoundError + +from ..lowlevel import checkpoint +from ._eventloop import get_async_backend +from ._exceptions import BusyResourceError +from ._tasks import CancelScope +from ._testing import TaskInfo, get_current_task + + +@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 AsyncLibraryNotFoundError: + 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 AsyncLibraryNotFoundError: + 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() + event = Event() + self._waiters.append(event) + self.release() + try: + await event.wait() + except BaseException: + if not event.is_set(): + self._waiters.remove(event) + + raise + finally: + with CancelScope(shield=True): + await self.acquire() + + 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 AsyncLibraryNotFoundError: + 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 AsyncLibraryNotFoundError: + 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, + ) -> bool | 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. + + """ + 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, + ) -> bool | 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.11/site-packages/anyio/_core/_tasks.py b/venv/lib/python3.11/site-packages/anyio/_core/_tasks.py new file mode 100644 index 0000000..fe49015 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_tasks.py @@ -0,0 +1,158 @@ +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 + """ + + 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) -> None: + """Cancel this scope immediately.""" + 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`\\] + + """ + 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 + + """ + 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 + + """ + return get_async_backend().current_effective_deadline() + + +def create_task_group() -> TaskGroup: + """ + Create a task group. + + :return: a task group + + """ + return get_async_backend().create_task_group() diff --git a/venv/lib/python3.11/site-packages/anyio/_core/_tempfile.py b/venv/lib/python3.11/site-packages/anyio/_core/_tempfile.py new file mode 100644 index 0000000..26d70ec --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_tempfile.py @@ -0,0 +1,616 @@ +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 + (Python 3.10+). + :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, + } + if sys.version_info >= (3, 10): + params["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.11/site-packages/anyio/_core/_testing.py b/venv/lib/python3.11/site-packages/anyio/_core/_testing.py new file mode 100644 index 0000000..9e28b22 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/_core/_testing.py @@ -0,0 +1,78 @@ +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 + + """ + 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 + + """ + 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.11/site-packages/anyio/_core/_typedattr.py b/venv/lib/python3.11/site-packages/anyio/_core/_typedattr.py new file mode 100644 index 0000000..f358a44 --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio/abc/__init__.py b/venv/lib/python3.11/site-packages/anyio/abc/__init__.py new file mode 100644 index 0000000..3d3b61c --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/abc/__init__.py @@ -0,0 +1,55 @@ +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 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 Listener as Listener +from ._streams import ObjectReceiveStream as ObjectReceiveStream +from ._streams import ObjectSendStream as ObjectSendStream +from ._streams import ObjectStream as ObjectStream +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.11/site-packages/anyio/abc/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e534b8f1ecbe3dff660fbb8f578e33b8f7c792b GIT binary patch literal 2891 zcmbuA&u7VMsz_b!38_*g)Jr5T6{o%#$H7B<>+0>-pLsL;cIM5S^{(Dxl4zm+?a_%y^%x>Jxx!VYt zGL|`qfWtV*oYTO)xR-N}(Pw6GhI21)Kknz;2b{%O&KckVJixghcn}YA&H@kNAVi5|D#T%ZIONnYi zI{|apVsmv*qC{FJm3`1M7hza$YtQK{)6DzP8!{_aeYNhA`=mnjJ#zZyo)dow(sb%f zG@Z@)jf3NXMTw!SWrMVfGje8x5OLsacQbZRyKqV76e2{qr}X5#L?D1)vD`uK`mDb_wt{!&PO%3 zMxm3kqX`be-ecHym3B8AQ1SfSIF$VX1YyPD2gac?G-;SggbDlOpfM(KCJ81% zAP${jzL4TV>K%HHjmj}kSaBi!kR>|Hnpvd+$t)=ByRl1cOMlA0D0GfJkY_T_|LIMy01Fi)2Or#=Y5eyD~Mg!WXUMw~!a6i$J>L!cO38blpe zrLMEDySp$k#ZpbSA4Lf98+r$d-ftH7R9f8M-!Br=eyo!{+o-X!D8gp#6%D;ytk&IK z+qzP?bgAe-?JPneJyCavQ{)?7gbgn$if-wyq71E;A*tgS{a;BU2{LxI)y}T{IE2!fXYTX$ z=j%V-{`vNc&7U?8Gr6No?l3ibl$t$89a2LMHhejGu>WlTm-x%_p`1UG^MA@qf5=O} jKRlFIkL1;3Bz4dFW4UMYQF!>@H(jxVje`xk2IuKNg$`BS literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_eventloop.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_eventloop.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e82fd09daa2f0f40827850969e7dc066743afff GIT binary patch literal 16445 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_resources.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_resources.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5f9058208094e25e283a42cfbdcdbd24c6d6b2e GIT binary patch literal 1822 zcmah}&2Jk;6rb5$uh-6pliH9Hin{6rS)#ToZWXGOMyNuRNRX&Vi|BT|Gl|{ohnZRD ziynd+p@NV&25y{!qVRuk%`w_jB_ssm;wqec>U*~QA9s_eoIN>xT5%nlV-UyAz^vuZeEG?U1DY89V^Hx}n9M7S| zAj09LBTC2#{CV>#2DwAHeL#3wn7=qjaPA5GV{MgJR!Ot^CyGs)O|dvmQkM3TST&8T zymWi{BayOfmUUDrS&&8|?Is*7XVyRz9Tse^?e+yslySVrWJcG5@$PyUpGD7afp|y+ z@hB&r!Kr6*!?XB2_-1(}eu>Y*Xp1th^V)%R1lA`n_VFA(2YxoPnI*Lw2cHO)3}hho zeyzIDmd4Jx9j1gEgiI-SJ&`U8Ly!_BSSJ)N!7 zO~mfz1ExKCpv`uAX-iujlgz@!(t(gOJKsKdkwln8{xJ;aSV13xct{?RRdP&MjZ880;B$JR`q?R!}9&T%Y`JgE;J2v0p0lnzI}35t3R1K2a#ls*a`d; zDrB^X^t0QLsrPpR(MPvFcOSVcNi4E5T5Yj#)F|jDYFls888r&EH_=+SMPT7^<7U99 zF~icEVD{5kSsaSx_86|*m*zckXnw7)+bWSYu!kzQ^Yk?>4Y$OAI@;~#t_b9_H$k??)2w&&c9wu|Kt@_U}Ad{_5_*-F-T=7bsxxGWlUc&pt!d->=YX*PjE@fy?y( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_sockets.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_sockets.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6949a8359f4a9e41b4761cf9964fbadfb19b7df7 GIT binary patch literal 11213 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_streams.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_streams.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17a682f34ff497a27aa84d5fdf7ba973b3274667 GIT binary patch literal 9609 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_subprocesses.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..110196847544c7672b2d460bb0b076aacc2bd775 GIT binary patch literal 3669 zcmcInTW=dh6rQ!$m-v#BOKB;hjEahCXxA!Gfh`&e$0z+suaTtgSk^W)9ja%h`FS z&@6=Qyj^r=nlnzRSyD)bED=`NA*{#?53__khHvyV%WP(i)JjjWTT_Cv;kur0_?G8N z=*}8#=?la39qw;=3^;`~YtuDs`BaGns#j#+HE(h0b%n`mnPBc}-{-fu$*pa^<_m5( z!7Q@YxXYrx8L5t_8vQ8y4Vdr&;iRcB(#$ZWndK^5Wa^Ik5Fn2enPv|7$60=YpAY$k z34Q_iZ?e(^zsP4o4duflhxC;~+zD1a0#^=kC)u$haFr1E7MnW)R~_NzkHF2c1z5pT zL19&RCYN$>>55AYT$L^1xn5V&Z7w7%DD^gI!?X=48!g#wcOtm9>UFr=(t^C;epk3b z)^dFlS2upJ{SzU|KIZFnqF_QQpfWSKTcV@qwqg0S>-v^W{Vh&Mb5nlb@}*WvV2wye zBLv|fH9f}Bu#{ASUU@_wDS;}vy&=&E`eMDlZHRiW*Q;~K`_AIqp54VVB+UyjYi(&o6Wg^PaKEW!-T5mRC30W?esUo=dIM57Zu5Kd6l2r(v%O>LmL6 z7kqvUKl{)lfx6!wR@TQ2i@@;pddlA4BXOWJBBGmb1iS8KJjL?4K)-dtP0LuFt3+=+!H>^~G< zTV7hfcI%r~i~3&Lpp;@wqmpyj$tgAl?8Ht(Ta`kj*5} z!CV~UgmoMcVdSD9i$&;95#HYurPnPCN-BL)j{I*CyuN(n#($3BJ+S=9;Hii@$W81~ z2$4961cMdiWmu5~o*8BaNc`ZInM};zlE`62rUs3~<7_zC8>u)>l@OR;5860#}s>-2i6iY>L=YYB!yF)_PI}!jmAbrqz4(4Ox)&B5zw4;0eOXUrN{y-*n|1l z#{*tt+|}dbXa4kFUqol&(g7C-y5Wg%XG`C3nIRap+)me@axrq!XO=st#-@hdtK(Ll zoVct^Z|Fy_Gt}$)(_5Mc(?DP_n=%#pOJlZ9k+h$^&LS=ZMDt(U1!7}%LI1{>T`RCF zE6BkkGj3y5uc_fi4eL^b2)QFPO`+dQwcp3~v7o5yuHkT94@$c3c&uwbDdKocl5u1#PBmUY`Isc~ z$e1Vj**!Et$z2$dn2aF!GrMzVs3JcfBUPL%CWn#8uf#|t_oaf9#`G{a97*O?a#uoh zOefJWl0q+q=$KBT;}NuANeK_Pa4A-570iN-E?iF`3j~~LB*?-|E?Rgz4Z}_6&_#p7sbz`6#GJa0uVem<*z`7Sw&Iy$eG>o_X#<@JO1vG nQ@i8u6LNNU{M{p;?!N3D=C3IVy8h~)pPgsX==0Zr!g&1y8vBA- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_tasks.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/abc/__pycache__/_tasks.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f02bcdfd58c977d32646fe38c0a68b2a720da3e GIT binary patch literal 4993 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/abc/_eventloop.py b/venv/lib/python3.11/site-packages/anyio/abc/_eventloop.py new file mode 100644 index 0000000..4cfce83 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/abc/_eventloop.py @@ -0,0 +1,376 @@ +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, + TypeVar, + Union, + overload, +) + +if sys.version_info >= (3, 11): + from typing import TypeVarTuple, Unpack +else: + from typing_extensions import TypeVarTuple, Unpack + +if sys.version_info >= (3, 10): + from typing import TypeAlias +else: + from typing_extensions import TypeAlias + +if TYPE_CHECKING: + from _typeshed import HasFileno + + from .._core._synchronization import CapacityLimiter, Event, Lock, Semaphore + from .._core._tasks import CancelScope + from .._core._testing import TaskInfo + from ..from_thread import BlockingPortal + 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 = Union[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: + """ + + @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 + def create_blocking_portal(cls) -> BlockingPortal: + 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: HasFileno | int) -> None: + pass + + @classmethod + @abstractmethod + async def wait_writable(cls, obj: HasFileno | int) -> None: + 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.11/site-packages/anyio/abc/_resources.py b/venv/lib/python3.11/site-packages/anyio/abc/_resources.py new file mode 100644 index 0000000..10df115 --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio/abc/_sockets.py b/venv/lib/python3.11/site-packages/anyio/abc/_sockets.py new file mode 100644 index 0000000..1c6a450 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/abc/_sockets.py @@ -0,0 +1,194 @@ +from __future__ import annotations + +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 types import TracebackType +from typing import Any, TypeVar, Union + +from .._core._typedattr import ( + TypedAttributeProvider, + TypedAttributeSet, + typed_attribute, +) +from ._streams import ByteStream, Listener, UnreliableObjectStream +from ._tasks import TaskGroup + +IPAddressType = Union[str, IPv4Address, IPv6Address] +IPSockAddrType = tuple[str, int] +SockAddrType = Union[IPSockAddrType, str] +UDPPacketType = tuple[bytes, IPSockAddrType] +UNIXDatagramPacketType = tuple[bytes, str] +T_Retval = TypeVar("T_Retval") + + +class _NullAsyncContextManager: + async def __aenter__(self) -> None: + pass + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> bool | None: + return None + + +class SocketAttribute(TypedAttributeSet): + #: the address family of the underlying socket + family: AddressFamily = typed_attribute() + #: the local socket address of the underlying socket + local_address: SockAddrType = typed_attribute() + #: for IP addresses, the local port the underlying socket is bound to + local_port: int = typed_attribute() + #: the underlying stdlib socket object + raw_socket: socket.socket = typed_attribute() + #: the remote address the underlying socket is connected to + remote_address: SockAddrType = typed_attribute() + #: for IP addresses, the remote port the underlying socket is connected to + 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`. + """ + + +class UNIXSocketStream(SocketStream): + @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`. + """ + + @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`. + """ + + 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`. + """ + + +class UNIXDatagramSocket( + UnreliableObjectStream[UNIXDatagramPacketType], _SocketProvider +): + """ + Represents an unconnected Unix datagram socket. + + Supports all relevant extra attributes from :class:`~SocketAttribute`. + """ + + 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`. + """ diff --git a/venv/lib/python3.11/site-packages/anyio/abc/_streams.py b/venv/lib/python3.11/site-packages/anyio/abc/_streams.py new file mode 100644 index 0000000..f11d97b --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/abc/_streams.py @@ -0,0 +1,203 @@ +from __future__ import annotations + +from abc import abstractmethod +from collections.abc import Callable +from typing import Any, Generic, TypeVar, Union + +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 + + @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 + + @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 = Union[ + UnreliableObjectReceiveStream[bytes], ByteReceiveStream +] +#: Type alias for all unreliable bytes-oriented send streams. +AnyUnreliableByteSendStream = Union[UnreliableObjectSendStream[bytes], ByteSendStream] +#: Type alias for all unreliable bytes-oriented streams. +AnyUnreliableByteStream = Union[UnreliableObjectStream[bytes], ByteStream] +#: Type alias for all bytes-oriented receive streams. +AnyByteReceiveStream = Union[ObjectReceiveStream[bytes], ByteReceiveStream] +#: Type alias for all bytes-oriented send streams. +AnyByteSendStream = Union[ObjectSendStream[bytes], ByteSendStream] +#: Type alias for all bytes-oriented streams. +AnyByteStream = Union[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) + """ diff --git a/venv/lib/python3.11/site-packages/anyio/abc/_subprocesses.py b/venv/lib/python3.11/site-packages/anyio/abc/_subprocesses.py new file mode 100644 index 0000000..ce0564c --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio/abc/_tasks.py b/venv/lib/python3.11/site-packages/anyio/abc/_tasks.py new file mode 100644 index 0000000..f6e5c40 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/abc/_tasks.py @@ -0,0 +1,101 @@ +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, TypeVar, overload + +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) +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. + + :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 + :return: the value passed to ``task_status.started()`` + :raises RuntimeError: if the task finishes without calling + ``task_status.started()`` + + .. 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 | None: + """Exit the task group context waiting for all tasks to finish.""" diff --git a/venv/lib/python3.11/site-packages/anyio/abc/_testing.py b/venv/lib/python3.11/site-packages/anyio/abc/_testing.py new file mode 100644 index 0000000..7c50ed7 --- /dev/null +++ b/venv/lib/python3.11/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.11/site-packages/anyio/from_thread.py b/venv/lib/python3.11/site-packages/anyio/from_thread.py new file mode 100644 index 0000000..6179097 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/from_thread.py @@ -0,0 +1,527 @@ +from __future__ import annotations + +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 inspect import isawaitable +from threading import Lock, Thread, get_ident +from types import TracebackType +from typing import ( + Any, + Generic, + TypeVar, + cast, + overload, +) + +from ._core import _eventloop +from ._core._eventloop import get_async_backend, get_cancelled_exc_class, threadlocals +from ._core._synchronization import Event +from ._core._tasks import CancelScope, create_task_group +from .abc import AsyncBackend +from .abc._tasks import TaskStatus + +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 run( + func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]], *args: Unpack[PosArgsT] +) -> T_Retval: + """ + Call a coroutine function from a worker thread. + + :param func: a coroutine function + :param args: positional arguments for the callable + :return: the return value of the coroutine function + + """ + try: + async_backend = threadlocals.current_async_backend + token = threadlocals.current_token + except AttributeError: + raise RuntimeError( + "This function can only be run from an AnyIO worker thread" + ) from None + + return async_backend.run_async_from_thread(func, args, token=token) + + +def run_sync( + func: Callable[[Unpack[PosArgsT]], T_Retval], *args: Unpack[PosArgsT] +) -> 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 + :return: the return value of the callable + + """ + try: + async_backend = threadlocals.current_async_backend + token = threadlocals.current_token + except AttributeError: + raise RuntimeError( + "This function can only be run from an AnyIO worker thread" + ) from None + + return async_backend.run_sync_from_thread(func, args, token=token) + + +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.""" + + def __new__(cls) -> BlockingPortal: + return get_async_backend().create_blocking_portal() + + def __init__(self) -> None: + self._event_loop_thread_id: int | None = get_ident() + self._stop_event = Event() + self._task_group = create_task_group() + self._cancelled_exc_class = get_cancelled_exc_class() + + 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 | None: + 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() + + 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() and self._event_loop_thread_id not in ( + None, + get_ident(), + ): + self.call(scope.cancel) + + try: + retval_or_awaitable = func(*args, **kwargs) + if isawaitable(retval_or_awaitable): + with CancelScope() as scope: + if future.cancelled(): + scope.cancel() + else: + future.add_done_callback(callback) + + retval = await retval_or_awaitable + else: + retval = retval_or_awaitable + except self._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. + + Implementers must ensure that the future is resolved when the task finishes. + + :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 + + """ + raise NotImplementedError + + @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 +) -> 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 + :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_: + future.set_result(portal_) + await portal_.sleep_until_stopped() + + def run_blocking_portal() -> None: + if future.set_running_or_notify_cancel(): + try: + _eventloop.run( + 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) + 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: + async_backend: AsyncBackend = threadlocals.current_async_backend + except AttributeError: + raise RuntimeError( + "This function can only be run from an AnyIO worker thread" + ) from None + + async_backend.check_cancelled() diff --git a/venv/lib/python3.11/site-packages/anyio/lowlevel.py b/venv/lib/python3.11/site-packages/anyio/lowlevel.py new file mode 100644 index 0000000..14c7668 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/lowlevel.py @@ -0,0 +1,161 @@ +from __future__ import annotations + +import enum +from dataclasses import dataclass +from typing import Any, Generic, Literal, TypeVar, overload +from weakref import WeakKeyDictionary + +from ._core._eventloop import get_async_backend + +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() + + +def current_token() -> object: + """ + Return a backend specific token object that can be used to get back to the event + loop. + + """ + return get_async_backend().current_token() + + +_run_vars: WeakKeyDictionary[Any, dict[str, Any]] = WeakKeyDictionary() +_token_wrappers: dict[Any, _TokenWrapper] = {} + + +@dataclass(frozen=True) +class _TokenWrapper: + __slots__ = "_token", "__weakref__" + _token: object + + +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 + + +class RunVar(Generic[T]): + """ + Like a :class:`~contextvars.ContextVar`, except scoped to the running event loop. + """ + + __slots__ = "_name", "_default" + + NO_VALUE_SET: Literal[_NoValueSet.NO_VALUE_SET] = _NoValueSet.NO_VALUE_SET + + _token_wrappers: set[_TokenWrapper] = 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[str, T]: + token = current_token() + try: + return _run_vars[token] + except KeyError: + run_vars = _run_vars[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._name] + 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._name, RunVar.NO_VALUE_SET)) + current_vars[self._name] = 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._name] + except KeyError: + pass + else: + self._current_vars[self._name] = token._value + + token._redeemed = True + + def __repr__(self) -> str: + return f"" diff --git a/venv/lib/python3.11/site-packages/anyio/py.typed b/venv/lib/python3.11/site-packages/anyio/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/anyio/pytest_plugin.py b/venv/lib/python3.11/site-packages/anyio/pytest_plugin.py new file mode 100644 index 0000000..21e4ab2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/pytest_plugin.py @@ -0,0 +1,272 @@ +from __future__ import annotations + +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 +import sniffio +from _pytest.fixtures import SubRequest +from _pytest.outcomes import Exit + +from ._core._eventloop import get_all_backends, get_async_backend +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 sniffio.current_async_library_cvar.get(None) is None: + # Since we're in control of the event loop, we can cache the name of the + # async library + token = sniffio.current_async_library_cvar.set(backend_name) + _runner_stack.callback(sniffio.current_async_library_cvar.reset, 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_configure(config: Any) -> None: + config.addinivalue_line( + "markers", + "anyio: mark the (coroutine function) test to be run asynchronously via anyio.", + ) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_fixture_setup(fixturedef: Any, request: Any) -> Generator[Any]: + def wrapper( + *args: Any, 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: Any, name: Any, obj: Any) -> None: + if collector.istestfunction(obj, name): + inner_func = obj.hypothesis.inner_test if hasattr(obj, "hypothesis") else obj + if iscoroutinefunction(inner_func): + marker = collector.get_closest_marker("anyio") + own_markers = getattr(obj, "pytestmark", ()) + if marker or any(marker.name == "anyio" for marker in own_markers): + pytest.mark.usefixtures("anyio_backend")(obj) + + +@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_all_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.11/site-packages/anyio/streams/__init__.py b/venv/lib/python3.11/site-packages/anyio/streams/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed566e892a4a39e470cf7c475ceb49235bd98c42 GIT binary patch literal 192 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/file.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/file.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..faac8f46bacb5f46700243b487b52230ef54f7d8 GIT binary patch literal 8133 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 D3_ESX literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/memory.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/memory.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..349b98af9d0548bd6444023508a1a565b3eeb265 GIT binary patch literal 15970 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/stapled.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/stapled.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14b3ff4d0485c676383a708e5cda81a30de544da GIT binary patch literal 8259 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/tls.cpython-311.pyc b/venv/lib/python3.11/site-packages/anyio/streams/__pycache__/tls.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..073f69cc5953ceae8dd6c6a3a8b98b1e0b969503 GIT binary patch literal 18414 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/anyio/streams/buffered.py b/venv/lib/python3.11/site-packages/anyio/streams/buffered.py new file mode 100644 index 0000000..f5d5e83 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/streams/buffered.py @@ -0,0 +1,119 @@ +from __future__ import annotations + +from collections.abc import Callable, Mapping +from dataclasses import dataclass, field +from typing import Any + +from .. import ClosedResourceError, DelimiterNotFound, EndOfStream, IncompleteRead +from ..abc import AnyByteReceiveStream, ByteReceiveStream + + +@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 + + 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) diff --git a/venv/lib/python3.11/site-packages/anyio/streams/file.py b/venv/lib/python3.11/site-packages/anyio/streams/file.py new file mode 100644 index 0000000..f492464 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/streams/file.py @@ -0,0 +1,148 @@ +from __future__ import annotations + +from collections.abc import Callable, Mapping +from io import SEEK_SET, UnsupportedOperation +from os import PathLike +from pathlib import Path +from typing import Any, BinaryIO, cast + +from .. import ( + BrokenResourceError, + ClosedResourceError, + EndOfStream, + TypedAttributeSet, + to_thread, + typed_attribute, +) +from ..abc import ByteReceiveStream, ByteSendStream + + +class FileStreamAttribute(TypedAttributeSet): + #: the open file descriptor + file: BinaryIO = 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: BinaryIO): + 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(cast(BinaryIO, 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(cast(BinaryIO, 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.11/site-packages/anyio/streams/memory.py b/venv/lib/python3.11/site-packages/anyio/streams/memory.py new file mode 100644 index 0000000..83bf1d9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/streams/memory.py @@ -0,0 +1,317 @@ +from __future__ import annotations + +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, + 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, + source=self, + ) diff --git a/venv/lib/python3.11/site-packages/anyio/streams/stapled.py b/venv/lib/python3.11/site-packages/anyio/streams/stapled.py new file mode 100644 index 0000000..80f64a2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/streams/stapled.py @@ -0,0 +1,141 @@ +from __future__ import annotations + +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.11/site-packages/anyio/streams/text.py b/venv/lib/python3.11/site-packages/anyio/streams/text.py new file mode 100644 index 0000000..f1a1127 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/streams/text.py @@ -0,0 +1,147 @@ +from __future__ import annotations + +import codecs +from collections.abc import Callable, Mapping +from dataclasses import InitVar, dataclass, field +from typing import Any + +from ..abc import ( + AnyByteReceiveStream, + AnyByteSendStream, + AnyByteStream, + ObjectReceiveStream, + ObjectSendStream, + ObjectStream, +) + + +@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, + } diff --git a/venv/lib/python3.11/site-packages/anyio/streams/tls.py b/venv/lib/python3.11/site-packages/anyio/streams/tls.py new file mode 100644 index 0000000..70a41cc --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/streams/tls.py @@ -0,0 +1,352 @@ +from __future__ import annotations + +import logging +import re +import ssl +import sys +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from functools import wraps +from typing import Any, TypeVar + +from .. import ( + BrokenResourceError, + EndOfStream, + aclose_forcefully, + get_cancelled_exc_class, + to_thread, +) +from .._core._typedattr import TypedAttributeSet, typed_attribute +from ..abc import AnyByteStream, ByteStream, Listener, TaskGroup + +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") +_PCTRTT = tuple[tuple[str, str], ...] +_PCTRTTT = 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, + } diff --git a/venv/lib/python3.11/site-packages/anyio/to_interpreter.py b/venv/lib/python3.11/site-packages/anyio/to_interpreter.py new file mode 100644 index 0000000..8a2e993 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/to_interpreter.py @@ -0,0 +1,218 @@ +from __future__ import annotations + +import atexit +import os +import pickle +import sys +from collections import deque +from collections.abc import Callable +from textwrap import dedent +from typing import Any, Final, TypeVar + +from . import current_time, to_thread +from ._core._exceptions import BrokenWorkerIntepreter +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 + +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 +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") + + +class Worker: + _run_func = compile( + dedent(""" + import _interpqueues as queues + import _interpreters as interpreters + from pickle import loads, dumps, HIGHEST_PROTOCOL + + item = queues.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: + queues.put(queue_id, (retval, is_exception), FMT_UNPICKLED, UNBOUND) + except interpreters.NotShareableError: + retval = dumps(retval, HIGHEST_PROTOCOL) + queues.put(queue_id, (retval, is_exception), FMT_PICKLED, UNBOUND) + """), + "", + "exec", + ) + + last_used: float = 0 + + _initialized: bool = False + _interpreter_id: int + _queue_id: int + + def initialize(self) -> None: + import _interpqueues as queues + import _interpreters as interpreters + + self._interpreter_id = interpreters.create() + self._queue_id = queues.create(2, FMT_UNPICKLED, UNBOUND) + self._initialized = True + interpreters.set___main___attrs( + self._interpreter_id, + { + "queue_id": self._queue_id, + "FMT_PICKLED": FMT_PICKLED, + "FMT_UNPICKLED": FMT_UNPICKLED, + "UNBOUND": UNBOUND, + }, + ) + + def destroy(self) -> None: + import _interpqueues as queues + import _interpreters as interpreters + + if self._initialized: + interpreters.destroy(self._interpreter_id) + queues.destroy(self._queue_id) + + def _call( + self, + func: Callable[..., T_Retval], + args: tuple[Any], + ) -> tuple[Any, bool]: + import _interpqueues as queues + import _interpreters as interpreters + + if not self._initialized: + self.initialize() + + payload = pickle.dumps((func, args), pickle.HIGHEST_PROTOCOL) + queues.put(self._queue_id, payload, FMT_PICKLED, UNBOUND) + + res: Any + is_exception: bool + if exc_info := interpreters.exec(self._interpreter_id, self._run_func): + raise BrokenWorkerIntepreter(exc_info) + + (res, is_exception), fmt = queues.get(self._queue_id)[:2] + if fmt == FMT_PICKLED: + res = pickle.loads(res) + + return res, is_exception + + async def call( + self, + func: Callable[..., T_Retval], + args: tuple[Any], + limiter: CapacityLimiter, + ) -> T_Retval: + result, is_exception = await to_thread.run_sync( + self._call, + func, + args, + limiter=limiter, + ) + if is_exception: + raise result + + return result + + +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. + + If the ``cancellable`` option is enabled and the task waiting for its completion is + cancelled, the call will still run its course but its return value (or any raised + exception) will be ignored. + + .. warning:: This feature is **experimental**. The upstream interpreter API has not + yet been finalized or thoroughly tested, so don't rely on this for anything + mission critical. + + :param func: a callable + :param args: positional arguments for the callable + :param limiter: capacity limiter to use to limit the total amount of subinterpreters + running (if omitted, the default limiter is used) + :return: the result of the call + :raises BrokenWorkerIntepreter: if there's an internal error in a subinterpreter + + """ + if sys.version_info <= (3, 13): + raise RuntimeError("subinterpreters require at least Python 3.13") + + 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 worker.call(func, args, 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 that is 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.11/site-packages/anyio/to_process.py b/venv/lib/python3.11/site-packages/anyio/to_process.py new file mode 100644 index 0000000..495de2a --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/to_process.py @@ -0,0 +1,258 @@ +from __future__ import annotations + +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) + :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.11/site-packages/anyio/to_thread.py b/venv/lib/python3.11/site-packages/anyio/to_thread.py new file mode 100644 index 0000000..5070516 --- /dev/null +++ b/venv/lib/python3.11/site-packages/anyio/to_thread.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +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 ``cancellable`` 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) + :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 + + """ + return get_async_backend().current_default_thread_limiter() diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/LICENSE b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/LICENSE new file mode 100644 index 0000000..11069ed --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/METADATA b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/METADATA new file mode 100644 index 0000000..96f0bdf --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/METADATA @@ -0,0 +1,330 @@ +Metadata-Version: 2.2 +Name: bcrypt +Version: 4.3.0 +Summary: Modern password hashing for your software and your servers +Author-email: The Python Cryptographic Authority developers +License: Apache-2.0 +Project-URL: homepage, https://github.com/pyca/bcrypt/ +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: 3 +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 +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +License-File: LICENSE +Provides-Extra: tests +Requires-Dist: pytest!=3.3.0,>=3.2.1; extra == "tests" +Provides-Extra: typecheck +Requires-Dist: mypy; extra == "typecheck" + +bcrypt +====== + +.. image:: https://img.shields.io/pypi/v/bcrypt.svg + :target: https://pypi.org/project/bcrypt/ + :alt: Latest Version + +.. image:: https://github.com/pyca/bcrypt/workflows/CI/badge.svg?branch=main + :target: https://github.com/pyca/bcrypt/actions?query=workflow%3ACI+branch%3Amain + +Acceptable password hashing for your software and your servers (but you should +really use argon2id or scrypt) + + +Installation +============ + +To install bcrypt, simply: + +.. code:: console + + $ pip install bcrypt + +Note that bcrypt should build very easily on Linux provided you have a C +compiler and a Rust compiler (the minimum supported Rust version is 1.56.0). + +For Debian and Ubuntu, the following command will ensure that the required dependencies are installed: + +.. code:: console + + $ sudo apt-get install build-essential cargo + +For Fedora and RHEL-derivatives, the following command will ensure that the required dependencies are installed: + +.. code:: console + + $ sudo yum install gcc cargo + +For Alpine, the following command will ensure that the required dependencies are installed: + +.. code:: console + + $ apk add --update musl-dev gcc cargo + + +Alternatives +============ + +While bcrypt remains an acceptable choice for password storage, depending on your specific use case you may also want to consider using scrypt (either via `standard library`_ or `cryptography`_) or argon2id via `argon2_cffi`_. + +Changelog +========= + +Unreleased +---------- + +* Dropped support for Python 3.7. +* We now support free-threaded Python 3.13. +* We now support PyPy 3.11. +* We now publish wheels for free-threaded Python 3.13, for PyPy 3.11 on + ``manylinux``, and for ARMv7l on ``manylinux``. + +4.2.1 +----- + +* Bump Rust dependency versions - this should resolve crashes on Python 3.13 + free-threaded builds. +* We no longer build ``manylinux`` wheels for PyPy 3.9. + +4.2.0 +----- + +* Bump Rust dependency versions +* Removed the ``BCRYPT_ALLOW_RUST_163`` environment variable. + +4.1.3 +----- + +* Bump Rust dependency versions + +4.1.2 +----- + +* Publish both ``py37`` and ``py39`` wheels. This should resolve some errors + relating to initializing a module multiple times per process. + +4.1.1 +----- + +* Fixed the type signature on the ``kdf`` method. +* Fixed packaging bug on Windows. +* Fixed incompatibility with passlib package detection assumptions. + +4.1.0 +----- + +* Dropped support for Python 3.6. +* Bumped MSRV to 1.64. (Note: Rust 1.63 can be used by setting the ``BCRYPT_ALLOW_RUST_163`` environment variable) + +4.0.1 +----- + +* We now build PyPy ``manylinux`` wheels. +* Fixed a bug where passing an invalid ``salt`` to ``checkpw`` could result in + a ``pyo3_runtime.PanicException``. It now correctly raises a ``ValueError``. + +4.0.0 +----- + +* ``bcrypt`` is now implemented in Rust. Users building from source will need + to have a Rust compiler available. Nothing will change for users downloading + wheels. +* We no longer ship ``manylinux2010`` wheels. Users should upgrade to the latest + ``pip`` to ensure this doesn’t cause issues downloading wheels on their + platform. We now ship ``manylinux_2_28`` wheels for users on new enough platforms. +* ``NUL`` bytes are now allowed in inputs. + + +3.2.2 +----- + +* Fixed packaging of ``py.typed`` files in wheels so that ``mypy`` works. + +3.2.1 +----- + +* Added support for compilation on z/OS +* The next release of ``bcrypt`` with be 4.0 and it will require Rust at + compile time, for users building from source. There will be no additional + requirement for users who are installing from wheels. Users on most + platforms will be able to obtain a wheel by making sure they have an up to + date ``pip``. The minimum supported Rust version will be 1.56.0. +* This will be the final release for which we ship ``manylinux2010`` wheels. + Going forward the minimum supported manylinux ABI for our wheels will be + ``manylinux2014``. The vast majority of users will continue to receive + ``manylinux`` wheels provided they have an up to date ``pip``. + + +3.2.0 +----- + +* Added typehints for library functions. +* Dropped support for Python versions less than 3.6 (2.7, 3.4, 3.5). +* Shipped ``abi3`` Windows wheels (requires pip >= 20). + +3.1.7 +----- + +* Set a ``setuptools`` lower bound for PEP517 wheel building. +* We no longer distribute 32-bit ``manylinux1`` wheels. Continuing to produce + them was a maintenance burden. + +3.1.6 +----- + +* Added support for compilation on Haiku. + +3.1.5 +----- + +* Added support for compilation on AIX. +* Dropped Python 2.6 and 3.3 support. +* Switched to using ``abi3`` wheels for Python 3. If you are not getting a + wheel on a compatible platform please upgrade your ``pip`` version. + +3.1.4 +----- + +* Fixed compilation with mingw and on illumos. + +3.1.3 +----- +* Fixed a compilation issue on Solaris. +* Added a warning when using too few rounds with ``kdf``. + +3.1.2 +----- +* Fixed a compile issue affecting big endian platforms. +* Fixed invalid escape sequence warnings on Python 3.6. +* Fixed building in non-UTF8 environments on Python 2. + +3.1.1 +----- +* Resolved a ``UserWarning`` when used with ``cffi`` 1.8.3. + +3.1.0 +----- +* Added support for ``checkpw``, a convenience method for verifying a password. +* Ensure that you get a ``$2y$`` hash when you input a ``$2y$`` salt. +* Fixed a regression where ``$2a`` hashes were vulnerable to a wraparound bug. +* Fixed compilation under Alpine Linux. + +3.0.0 +----- +* Switched the C backend to code obtained from the OpenBSD project rather than + openwall. +* Added support for ``bcrypt_pbkdf`` via the ``kdf`` function. + +2.0.0 +----- +* Added support for an adjustible prefix when calling ``gensalt``. +* Switched to CFFI 1.0+ + +Usage +----- + +Password Hashing +~~~~~~~~~~~~~~~~ + +Hashing and then later checking that a password matches the previous hashed +password is very simple: + +.. code:: pycon + + >>> import bcrypt + >>> password = b"super secret password" + >>> # Hash a password for the first time, with a randomly-generated salt + >>> hashed = bcrypt.hashpw(password, bcrypt.gensalt()) + >>> # Check that an unhashed password matches one that has previously been + >>> # hashed + >>> if bcrypt.checkpw(password, hashed): + ... print("It Matches!") + ... else: + ... print("It Does not Match :(") + +KDF +~~~ + +As of 3.0.0 ``bcrypt`` now offers a ``kdf`` function which does ``bcrypt_pbkdf``. +This KDF is used in OpenSSH's newer encrypted private key format. + +.. code:: pycon + + >>> import bcrypt + >>> key = bcrypt.kdf( + ... password=b'password', + ... salt=b'salt', + ... desired_key_bytes=32, + ... rounds=100) + + +Adjustable Work Factor +~~~~~~~~~~~~~~~~~~~~~~ +One of bcrypt's features is an adjustable logarithmic work factor. To adjust +the work factor merely pass the desired number of rounds to +``bcrypt.gensalt(rounds=12)`` which defaults to 12): + +.. code:: pycon + + >>> import bcrypt + >>> password = b"super secret password" + >>> # Hash a password for the first time, with a certain number of rounds + >>> hashed = bcrypt.hashpw(password, bcrypt.gensalt(14)) + >>> # Check that a unhashed password matches one that has previously been + >>> # hashed + >>> if bcrypt.checkpw(password, hashed): + ... print("It Matches!") + ... else: + ... print("It Does not Match :(") + + +Adjustable Prefix +~~~~~~~~~~~~~~~~~ + +Another one of bcrypt's features is an adjustable prefix to let you define what +libraries you'll remain compatible with. To adjust this, pass either ``2a`` or +``2b`` (the default) to ``bcrypt.gensalt(prefix=b"2b")`` as a bytes object. + +As of 3.0.0 the ``$2y$`` prefix is still supported in ``hashpw`` but deprecated. + +Maximum Password Length +~~~~~~~~~~~~~~~~~~~~~~~ + +The bcrypt algorithm only handles passwords up to 72 characters, any characters +beyond that are ignored. To work around this, a common approach is to hash a +password with a cryptographic hash (such as ``sha256``) and then base64 +encode it to prevent NULL byte problems before hashing the result with +``bcrypt``: + +.. code:: pycon + + >>> password = b"an incredibly long password" * 10 + >>> hashed = bcrypt.hashpw( + ... base64.b64encode(hashlib.sha256(password).digest()), + ... bcrypt.gensalt() + ... ) + +Compatibility +------------- + +This library should be compatible with py-bcrypt and it will run on Python +3.8+ (including free-threaded builds), and PyPy 3. + +Security +-------- + +``bcrypt`` follows the `same security policy as cryptography`_, if you +identify a vulnerability, we ask you to contact us privately. + +.. _`same security policy as cryptography`: https://cryptography.io/en/latest/security.html +.. _`standard library`: https://docs.python.org/3/library/hashlib.html#hashlib.scrypt +.. _`argon2_cffi`: https://argon2-cffi.readthedocs.io +.. _`cryptography`: https://cryptography.io/en/latest/hazmat/primitives/key-derivation-functions/#cryptography.hazmat.primitives.kdf.scrypt.Scrypt diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/RECORD b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/RECORD new file mode 100644 index 0000000..9ab1a92 --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/RECORD @@ -0,0 +1,12 @@ +bcrypt-4.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +bcrypt-4.3.0.dist-info/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850 +bcrypt-4.3.0.dist-info/METADATA,sha256=95qX7ziIfmOF0kNM95YZuWhLVfFy-6EtssVvf1ZgeWg,10042 +bcrypt-4.3.0.dist-info/RECORD,, +bcrypt-4.3.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +bcrypt-4.3.0.dist-info/WHEEL,sha256=XlovOtcAZFqrc4OSNBtc5R3yDeRHyhWP24RdDnylFpY,111 +bcrypt-4.3.0.dist-info/top_level.txt,sha256=BkR_qBzDbSuycMzHWE1vzXrfYecAzUVmQs6G2CukqNI,7 +bcrypt/__init__.py,sha256=cv-NupIX6P7o6A4PK_F0ur6IZoDr3GnvyzFO9k16wKQ,1000 +bcrypt/__init__.pyi,sha256=ITUCB9mPVU8sKUbJQMDUH5YfQXZb1O55F9qvKZR_o8I,333 +bcrypt/__pycache__/__init__.cpython-311.pyc,, +bcrypt/_bcrypt.abi3.so,sha256=oMArVCuY_atg2H4SGNfM-zbfEgUOkd4qSiWn2nPqmXc,644928 +bcrypt/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/REQUESTED b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/WHEEL b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/WHEEL new file mode 100644 index 0000000..dd95e91 --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.8.2) +Root-Is-Purelib: false +Tag: cp39-abi3-manylinux_2_34_x86_64 + diff --git a/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/top_level.txt b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/top_level.txt new file mode 100644 index 0000000..7f0b6e7 --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt-4.3.0.dist-info/top_level.txt @@ -0,0 +1 @@ +bcrypt diff --git a/venv/lib/python3.11/site-packages/bcrypt/__init__.py b/venv/lib/python3.11/site-packages/bcrypt/__init__.py new file mode 100644 index 0000000..81a92fd --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt/__init__.py @@ -0,0 +1,43 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ._bcrypt import ( + __author__, + __copyright__, + __email__, + __license__, + __summary__, + __title__, + __uri__, + checkpw, + gensalt, + hashpw, + kdf, +) +from ._bcrypt import ( + __version_ex__ as __version__, +) + +__all__ = [ + "__author__", + "__copyright__", + "__email__", + "__license__", + "__summary__", + "__title__", + "__uri__", + "__version__", + "checkpw", + "gensalt", + "hashpw", + "kdf", +] diff --git a/venv/lib/python3.11/site-packages/bcrypt/__init__.pyi b/venv/lib/python3.11/site-packages/bcrypt/__init__.pyi new file mode 100644 index 0000000..12e4a2e --- /dev/null +++ b/venv/lib/python3.11/site-packages/bcrypt/__init__.pyi @@ -0,0 +1,10 @@ +def gensalt(rounds: int = 12, prefix: bytes = b"2b") -> bytes: ... +def hashpw(password: bytes, salt: bytes) -> bytes: ... +def checkpw(password: bytes, hashed_password: bytes) -> bool: ... +def kdf( + password: bytes, + salt: bytes, + desired_key_bytes: int, + rounds: int, + ignore_few_rounds: bool = False, +) -> bytes: ... diff --git a/venv/lib/python3.11/site-packages/bcrypt/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/bcrypt/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c1552264501a8d7850f8b43ebcc3a43e203c8b3 GIT binary patch literal 718 zcmc(czmC)}5XS9fcaz<0_KFkDy+I1jI?*DY09`}pf{`yViCH^|oIguC-h!S6@d`Xj z+LI9Inw74*iWx22fkcNb{WN2HK7BL(lBOGm>+Sc4@<+(nJtgNA{0<&(G5Ev^R&dK4 zm)r$1aG?y{LN44=F5OD5TqGkG%h;{u+HK^n*O6&7&`jvl%;`9~W iH^edIoFA{YJUFudiK~Dd{0(uM;O!Y7BijBF?f(LPkg@gv literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/bcrypt/_bcrypt.abi3.so b/venv/lib/python3.11/site-packages/bcrypt/_bcrypt.abi3.so new file mode 100755 index 0000000000000000000000000000000000000000..ae9f55b6df8e1b5062ad13fd04d5cf1741370f98 GIT binary patch literal 644928 zcmeFadwdkt{r|t43vA>vi?SLOWz}dy>m^apL_u~Tfmz*XDxk5V1R)TV%Sv`NsNiBk z&2+o{L~CnoYa45;vF)eEUTC0RHef?Q#RYFs+Y<4%F<#;g;*I^j-shZ2X5VI7`~5zC z|NI`^R%YfoXWr+1-sgSpXC}9l2j^rtoeuMt?Ks~teC2TX)Q#vfd1er>631cqce3Mn z5jJP&&Il)sikU~ZyrwvE>9kp1^W#767Iz)y(P4Q`#8)&*KFE&lrBZwIXnl^JNZmVH zJjai&N+~X(j^=Y&!1UbUe)$|fIw%1B)X^oc9Hb-t7gC%b3sgAsNMY$mvCui!&%E~H z9{sB1!C}T%`9^ptJ-70CX%~L{{*m$l^JvERZ9JzesU-gEgUSZSB`Q8sFMiCwNXjvf zrcY746Y*a*{+oNz0>_QV$B&34uYKc*=f8FJ&wexg^1lB)N@z-EyBYt{b5cJMvzr+G zJo|3?K%R~KZ!;b`e1uykBVscR*4tOZ@FRuak3b`ZUkW}___v|(Na45J#Cw;Go*^6V zh5V7?r8vF#kN>WK!AH_3+fGj#{xXW=NOD}T+lf3RC-)$| zBl*c0Hum3c!zbGKTd_^P+-D_V;ecg*ywYijr_}Osp(5=i1a8Yi;!T%*H-1+Js*q^c>?zT#k&uuS*^rjzx=>uUfNuQC)cP+VG-9jzxj_ z6^oYEtgTtTqApysc7Da|m1|bl%wK%<${KlZ<8O|20Ua@4&(waqc z)~;DKFT8fe>gE2`OXo>t=&^b0kepTWxkZb@E9(|5uL&<&ymTpv0j4O!Yt|x>ka`i4 z3?Y#vVVI|8?b_9A7D2nk;T3CEBlN6w;hMS;Ba(Ogby5M+udGJtCvORbD26$USJn+h zf$RBeBj%+{=7PGKwU;ekyBY~m3er`1JzZSCc;%vbi?6SlUkmdsHHk`qf>$qD6~dkQ zk6<^~~HMFn?XBW)UvutX#ajjuNM?=dD~5#$^y5yT~6xGRP+4ib9wH19kHv zSBE7akDypqTpdATlrxc9b5~qn11qc4RV)rKsjZ=?gtUulZop~9nxzrg6nb2=cvX#5 z64-P=6{UIUuUjyGPRWo%4CC_EIJWojqyOBGbETEoihSTwID zJb&%tB{f$sUUDr7L6Ry_7{bzVa0LNF$-8VtxV8+XPDG{zK!MqdBglTK!K}rZxjOVL zr9UGk(`KZCDPe9PI4`_7TmvsySp!K{jc~pwP)GH|3Q=hYKSr7Zt3qqmhRswDNhn`k z7eVQyng!KTXf2#@t&|N#Y;d4VML4Gh`KZn>TCS#U+Y+g zb|ZZDR0nFanrm^SN(6^Ri|Rwm(Wb1ep|Z7Tt*GZii^H`;;%C7@!{n($1bPH2DT12S z*E<$p4JUw^7KiJt0fLKHFOMu-|7wVD+*!R&og%vNfyWDG+DY zRmkbNmsqb5?;_EHg+-0J2>Dl!_G`te&`L*0v1@DAEm|V7HUljc_2Cezs|nXB-5jf6 zFxX=0%0)2uS}F#iS~NE+S6sb($&y8Nr`N4Hy_l|+(An9Jl}k^9Nh9^A)t8)o+SyYH zp6Qqy49uFn=*-j4a?G7Qd(qU>&pf?IoSijv#2ppp%#xwg;;BQYXIV~%!=82eFfJZ` z?#$Dtp>L4oa1Q-PXW8P)2}=LV!F;j2KS~{)m>HyV^MCaG=%Fi<4j)~Rm*vP4Qb%Ft zGz+uXQlj~<(=o;|R!NYO=?RjM`R_Q8QDF36<~r!WwJUeIKr?tG|H>`8>yiidCMnZVb(o{!v}e6W7^} zzYaa`azxcVlGk+mkI|DG=h&{;o#J||W4F4N@sAPllTLpU_g#*c)crq->(P$a)phvj z70@Tw@xHol5%+T(pR4Q0F?1gmQxn#%U*ZOS=KOVZH9DyHxfxF+1$N{!9#!1SxOrX3 zxI?WI_!z%H@hZlDq<9nKtuIJ@ni-EO-p2VqW%zc+dlm0syjsagF#e{}C&~Ch#Z!zQ zQH<=R-+h^OK3(yA8(w6?b;f_Gr6YC;R|iJ&xTjo z@DStgD}9=5c&iQXu;ED?p0eSN`!myP>XUE7i)^@V!>et0y$x@+;cYg&hw;!SvRDr? z-kz4+@jzyJe=}A3Nj~F~r%7I9!*#|d&XM7(YrHpXiLGTwv@@3G+n zj3>V%<#?&%fS=j^CLU9EV7%EaxsP$jk+Qwk8TZn}GJe&J`zA^rWqd%Byp{3hagrw( z?=6$Om+`2QlVZGhp-iviH<{_Z?@GztjGN&L8UK|E?_=ByUuDBXHoVD(x7zRy#&;-v zx*303@gBw#il-Pi~9d>1F)xE2P~j8GnZ+R4LyXKj$jRLyY^>bvxsx`~>4= zN=}mT8H)EZZp!ukE;C)%tMEmP-=nyX@uB=>+|;v{anlaQh^pDlS0cClV|NWap3nF$6~2)1BiBedKE}%xuVnl>#j6?L z9FlVCZFsW{Z?oYE8{WhC^D5o}#y?ct@#jqYnBnso|5Sx9WPDK7S0#)WDL>H}AAOy) zLlxsL#cLTqLh*XWx2Sr%iSbeuzJ+l!-ZsX~csm%MspNDsZp!Il{HH442N++VZS2BK~3SZ6mQpH1z-=lbx@rM*|X56Rpv6XQ%d^_WNl$-?PZz-N+ z{A0y?89%08+F^k4(^dVM|CdaAR&SN{fS2(iHGVH)+#IJ@F<$wIlvB^RPsxum-n?Gw z*~0jM;_WuP+lKer@If2y?#Q%*8E>Ht_c7kHL6t`v9eI{k z!-@|w?ug3p?k$;iFnOU3_u23&8y>RZO*XvMhIiQTqzzBmaL3k>)0=O@i)^@V!>et0 zy$x@+;cYfNVZ(cD_<#*}sf9eVzhvgS*M^ta@JhyulwVadZpyE>;mtO@&4wpzc#jPq zV7yf6>3Ss7A589L+|<9shF99~S{oj<;Vm}2-G+DD@Ln4}Xv5u)X4=6_Z=ntMF+ORd zst;{=i17_7d=uk474KlYXaY6_;+J6DM;o5;OESJw^>ca|ze$B3WIU%q)rXH|+Tmiw z3mLy#aUbKKD_+TXpi#=NW<2^$nXY=qi-MB3Fz%Qlc`M`5Qzh@<{BX$=oU8CXoU8D? zjQ6T|2N`cxa$JvR+U-7--h9RriWf58sdx$FW_X=(x3XI`;~}MIE#v!@{AR{|=PNri z-aB2{nejm-r^ALP8TZbVa#D=D?~vS;$h2Ga49VS$-?vHnPoWL>+3+gHKUZ>U88_ue z84r9{#@o!e8NSViCv5lt<4Kj?LB`)v@wz%Q?PJF4W&GE-Nj*y#A5grKalJ`~uVws) ziq|uKkK#>?H|xqz7$2A`c?aXIN=`T9_bQ&U;jV3&cDP@K&u9F96)$9bhvFrScPn1S z_-@5(8PCzB-Rc=P<85NxjJJhxGu{ryUsmyUGybLGDaH>eKFGKkK7V_r-A*!;pD?~k zah>t&6|Z94Ojj-AQ5C+P@oH6{H#457kbcs_cvOXNWxP`HHpYLb;!QCAPsIlq_kCN& zJIMH@-;?$!d?M3sy()YW43OqDyvt1prIL>V{h$tK1(C^@Z+CzPBH z#*<3V1mnAuoE{rKV8dO1%e0Rv$IE#0_hovE7&pV~HoV$~*W2)B#!KQd-ZsV?6z^fY z=yGZQUdA2YQGUXBbCu+du1q^3dwzp|4zvXF>cDKXWW$2!npfN zDZiC*htem(xGBGzaZ`ShaZ}F}<7uV8V@IZas+B(ZjQ5_c?8A7a($mNI4gVwUTxG*U zj5}_Z;hPx$j^Z7R`>vAu^f2DLO!8jFs~1b2VtlWX@9567!^w9@eexMkESGYM7&q-x z$#{FM3?E`Vq&|>P&v>uvE%VGTt1Qyod1)m97CB?%J7Y2Q$2v@ijk` z_9?O9m5jfq!q+l>>77zel=0TJQvVjlO*?lmp14kiPcYtFCwVvH_o{e%7=Kc6*RD)E zw5$AbGv225CwLjZ;zu%FMT|#Px^%|9O8-j68{ZytMOkT+NR;7=RaWi}s;|G=eTE>5> zc$D!AekS#4Vf-hGx7+Y;8$QUm?=ZZ$ieLWIndwd5C+%6n_<-V7jJMw-!`CzJRlJ39 zhfBuW%6L+RZ)3du=Td$<=gYU!lUcGrnH&1mkA9dTjWB4R`Iav5yTevEh|Ayw-+C z89(|Lsy?*g?KZrd@!OSsl8ld4cJ5((lH$FL|4GS7G5!O^2N-`?@j=GTcpZB)?R>8a z?_&ICin|&Ao#Oe7oASMk|5$}DWc+@`ix~GRJCrb9ptz6m4kbrt+|;MihF3BELnWu0 z@%t37Wn5S7V~FuBDttZTran=|?^fZP7=KXlX2$=bcnjmb_e#HQx8dE4zyF8~-^+OA zb+X+YWW4nY$sNyT`cJdsF2-B0l;PcsM<12(7TR#14X?7{A;!;mOv;Zko>cL+*zj(~ zi&n{f{wcV0Y;?0bk;oBI`?vm;1VB8F!WPG^_pR(bOS2FEmhR?U*MK)Zw;ng<0-i9~Z z@HQKsu;D#6e87gg{+?-vsPc0!@m9sF7*8l(&AGBql<^|vCrymsq4aEF+_X=E@uaFxx*2c1 zSn8i-e20=h$hg^_=J#gW`EwP%ka2SyRKob%Ps;M5Gya9*)r=qilnh_bxH&#;V|?H$ zRo^o1s8{}J!+RKaE4%eF?p1P9Hhh5bpwi#*YNp*TQ{2sXNO3RYKT*7h@y8U`ZFn`~ zhdr(A$@uw-H!*I8Z)Mz2;oBL1O7U*S2NmyO{KVZ-p8>`fD(>2!X*ZL5ZFq?duVj4k zGcw*<8y>acEsQTva@uWpH{+XC_+G}{NvTiC8=2`%&X?;%KE`|R6w6!=opJY1B(LQB z$C6huUfnEtHRB02{}5ulUGXU6$)}{8X2wHJ^8J?<#uG=%bhR;F^t3F$9gO$>T*^-{ zzEgdlD#^G**{z512a-~sUdCrWCwYqT0ab4gFn;-6QlI=cGxMwH2wBf~8IS%!hA-rN zx8y~P7pZ*oF@FEkQqL;J-9MCet7be}D(zg$_~33Sr=IcFIa2>9<3$tjpXZ@{94Own-jkJo;0a zt`^2CFOc$E8IP*>VLKRa-6iED7?1u)@@~cx=gE9YGG491_b~p$JyQP^Y;S7(eAH z8NQnF=KCeDWqjZXnXY=qqkoa%ql~vMkm+q^+@thqVZ2iH=UW-CzDCOF;QVJY-X!C# zFH1dp7>_aZ_>+%enHaLB^|nD!<;&%&*FmWxQ_2qoZZ`e8!U}N$zF5d9T#7ka72g zQhpKRN%{ajekF`2R6VRS-u`20w@SvFS4;WTjK84z3AK!y-xCNi?pP${)HDA3gizBF zWjt5ad##LDcSt?k828;G<##Y%t@?Ed#w*9l`l_4pgz8tM7>}xbn*)qDkCyrjGTu5} z`9puEKRCuoJ>8stq5OgIq)Klg=eJA$^fBH#TFS3v+^hBpS25mvq6}Znc(Oz4Q_HyT z5*a?kc;aoDkM)dyq&~FY%=o}KY5x|+o1;>G8{^exKZo&wa;awrXT$VdYhEr!+3kP4ByLm=tnYN1{nWrhw>A~Th;e8T<>K1iT4B2$Fz($X^F?R;*1a-(CF9W-r5&mmPyAZySpYB#$XPpbZ2l5uZD%1JR^y+ras#=UPyeO&Km`cKij(*9n?tKHH*MT|$y@iODh znhambc<2PFPc7p~RZc^US1yp@>lrUPL5}OAjQ6Sby@~OwRejRJcr*RMBm7z!cdK&U z#<)ZESKApsT8$Sv7%%#}v~v&RzTZhd>1BN2EXh-hx93Vd9q(o4mv^${F2)^dJm_Y; zw?*pXWjw0duR_M#)q5F5jQ74S%Y~2eR^{haj1P>J>8fVD_fx4)i1DrT2fXmBXWadJ z$)k*W&31utpG*2-E90#br9K^u4;(Lfg7M0CWVz^O{EqEXpCseH*)m^x7_X#1q=;WH z<8Jjm(iG!SGvD9O%=gMR8Lyl1#I2GSGX87TpDAKIFv~xY$+ zj5jw(|14DVif(0I^AJ+wFV0(Rc&(B{R+JW#lIks7dV=Il7A{M=&X(q&Rz`{?r@Iebd!@}LF{vmr7S$MvM7hAa3!q2qu zDhof$!fP#js)aXM_%sXeu<)}jyvM@NvGA0Imst3Kg_l~mOU-*wde5_PpM_7i@G1+R zVc|^{e!hh_Tlh>1Z?SNng|}O{-@=m?KFh*;EPS?w_gZ+Fg}c=Fozh!w;a&@$W8p;> zKG(uaEL^v6-NFMF9<}fbEWF9WFSPJh3lCa&%EBuw+@Z#ml&*^`+-KnzTX@vMD=oaq z!oO|d9Tt9xh4)zaJPYr&@c9-#VBrfa+@Z!9g%)0I;a6ICvxQ$};Ry?0WZ~TwUTxt?3tw#E0~UU@g%4Wz5)02) z;}^2$QVTD!@EQx(Eqs}US6cXT3$L~CS_^No@D&!`Y~j~fc$Pzuv+-Ec^xwPgr=p zg(oe1orU*W_>C5xvhbTM+^zbt)Q3IS!t*UWV&Ps3x9V>R^54_{THwDH_^$>2Yk~h- z;J+65uLb^Vf&W_IzZUraxdlGbj{i(=c*mv3a*gkdcIcZD;jDC0Z+ODBU8Foc?dAES z9qE(*j(@euKAh3D7&-R!rtv#@FJ05reqT~t@1kp(((g;)dVy}dk@l><45GJCApD|w zX?G;+%I$i5+zS)HjUBr2f^O_edmgG9?O1lYHn~xR(CP9{UZ)$M z>#@;#e5^w+{Xo~|exNrT%JVycN!@rk?OA^1Xve06 z_M-%}Na~x?+MS)Q&dAL{D?HPCZXh+a^EA4r19-XB6SL&Ny3D4EzxjEIy zz|ADs8f#?szmD;fg%o4tXjmrM?+qG*{l`MQZu~Rtxe@NtKMrQj(~W&;&pgCjyc4Dm zYUP7atissf3K&-OJHMAHxBAX zS1SCvL-?DYYza#Sj02SQ4L8D!%Y(72VaC_B#yeoDVC>vL!=cgIZNC%t%PAoH>Bd{q zCyWo%o+6P5VYcZ7rrESj-=l|(LqTJI!1yBV*^7(}8tJs>?n~&Tw|@cKV@P008U>!j^vbgz)urY zf#BGKg9D*cqBx_(2p(VGk@kFvyvwkU^s3MF_>845<~kmuC5g1>8DzCKIZ9%N<6l3Z z8<9bX#Szs&Ja^9tPKsIR^K34iwj*+}FVHMB2;B>wz;(A$q8*i4+7p2uL-iLbFRyN_ zhq{r0Wjo3TAvV4~mG+wiZN9__H_tqrJ zsf%2}c<#r?3T;}0#^`IZ{8d3?u1jxN?#1mnZUo8KjT=z#=HiH4dZtpzj?eJDkn6bS zl&jL7^DY`Iqk>SYnie%6z@9{OJ!-xB{%{v+foe`9v+uzldd;_@^|B;OQFyz)c z5%&cy-Izu3e)blncoyO%Rc1j#?m0r0S%r9%RB5LQBfehbX-JG;yQKoo&pT>zjjA-`$v@gL2&>NP1AzdytPBOx0w)!$lDqO}k4b6dp7ULWb%Ov>TTq zU6$*|C=Sc@k#OYUYtdPv`ZV{de;4I?#I>_RJlsgBl10sIh0~t(B-qj;Gm9eZPV&cp z9r-J`{Iuu0sQE|Ix9cb>ME}A>r0>yO-f((<{B@pxDag}HolB9PWnbs{yX~Jp^mXiU zx&8CIzs~bVXFM-DNYvSc74n1eY1?7iN6|W`gRvP8!A<(Vu?)YVEPQ+yG8uh&&dd06@^bhR^Pa$-}=Q-i$`nKV$ z_}#vJIG}$q7XP_-log1-U>b~v3*5ojX^n6|5s7NAMXP{Fwvu-K^z%beYoSDG-8WGB)He04VM0o{^hin_vJc@(edm+T4?}Q z@;Di^_(1Vq-Pn%7*rr7NSl#H+jodlNiYvCKJ(udE9WmFYof}dOpE|>+NqZVTJtgu_ zeFqJ>P{rpSCjwICL;mrVfe8BZ*SU3cQ_(3a4H}>6#!IQI(XHw~o`wrYqGUghw0sX` zaUXifse>=#RyKP7qKk^2X%KyUO9ww_ptDJRe9^xjHYWO~@X8XsA)SttKfn{X-pa}gTK38VVH1JMX1 zBCj(eug8hraFffSHLjx5I6C7E3FL2CflrT@k0W-4v?}Nq}%@iK9@LlssH1<`rE~ z3@Z?zL!w+g9Z7TdwxM-rdi>zsh1vbLX!b~ z;}ewOLnUsz7^a?DPH8IXI|Wsr0LKFK-9=aN8Bd~uLs!m?A;)8dcsA|%HImowew;k? zF`3{Ph&Co*bYTD*K28i6Ys(Pma3G;`>T<;2pG}ugCMc9Sn0oF#6imG*M5V4EULlW5?l>Q?8$&0M`pWV`53aLDx3510~Z=Vcn z&SoYqngalBE z9>r_uq4zmQ1qtoxJ=@8xuAFL$zuT6U%CRc%(J5=aOX_R#3tHvnVx_m2>|dBm5GOty zh0?VYbrGQw8ru(*6K~p+h9mYJV=>3?@m8;Cj<>}?+RWDf+#J7z@SyRhubLz9Yh{k0 zakDT(m6mA+VZg7LVc0yv3@}ftNY1c%+QfBk-;+`tm1Y?E4wVjR9@-ybXC7fXIcEXy zNPBu`!yzzhQRxVep&5y)wC8_)R2`tL3C2W!W2vY|d(cN1uHx3s!DDEa13{xCXoOI` zRik>#7VffRwhIct#H#=X{Y_q*PW*5nuJ*bO%a7uL%&EQz;lk-p|Xk*aO zOU)wV`cE3V2%|`c3#$52V7H?^3g?MQq)%s3Ec;R$-%h8ShwBe%#m}jpARi~c6aFUa zg79LqFjmp5PBpnd&Zt_5=iY{w#p&El#VDW7yr6~{p;B3buNBF908Nlcl59Sxz982m zXX>9t50kXgA!+g4NQMmQbR)|U<`gXeN?&2xbJi@R649VVkV@|VrKu!JkW8U$^>*%* zH%RB_GvfPqI#byZjUD3K?niuZj*xPW`n0F{eCZr$|H1`m|CY-34~@~Vb1X!u_>QMLBRR+MsDgxZAonAO_aCi113Hc;o$7@@^v!?@@Q3SC|I#16h9BI5NvyB> z!N#LW{(tTV#Y58KxvMf{{3m|!EtF8IGi8pOb*RNJcD0&HBb4xX=t><8|MFqKcsC>d z|HLnTOQkK-FY2d{0b*W#qnJtJ28IC-eSielZF)*}wIRJ?D|&eW}aeOsCNq zmg9S~zG!%-K49z)7%z$i713P?SDRG?x&lG!3Q#)(WBOpsrFj33&UGr~m2`%JlPkx| zIR#V;h!=q9#B0_NJ_;s!g88C`@YAy-?5H7O@!WZ0$gM<}jxmx5vx2DBjW^Sti71<- zAg)Nuc<%O}O9i2J?is?Qb}~hpq*|s-XbPDLDoDucYE=cG4-h{WhIYdQ+7yV3mC2;L zvAiHw4n9n+M6|)!^a3i5XhfD$4=c9?Eyl1bl#&O-73Tcg_T!)jAxCtDh9~MrsvizP z^pGE%)c;LUKTI!hguOzaekdy16{JX17`39p=qROV_N9EUV+bwRSJ40LMz&QLyDMlp zPP8Iz0Mv?5yIY(HV5F(tnLx+%mk;H_^qy1xfrD1IM{gLw3ecUZBh*-spvP2YvqE~5 zS$b8AG*p_UYvtjU)33VL7-5V5*tH(P`-D|!4{Mo>gcpm zLSzdB8S&i3_{0c3gEmg}RfK!Tb8AP*8>n;|3#8R#3wnl92EEbmEBjzUg=CPIJ}6R1 zHb9}#&3;}rVnsB)6snT$RLNf6BeDiW8~`^ zWiAND=6Lnk^)T@C>x1!}U3%$mU7NKVmxE+L^kr^FUj_sH!XPe-$etzAz(E=|(=0&T zQ*=1Ve~Y^P`Kg;;CIg8cp%^ZC7QUS8*h1TEp#mn(DvZI@jxR7=Y@l+69vOyp%g-hO zJ(vTj6muXLYNFT;-=8b)?@K+?i<)?7Do)JbQu(9wRI3Hf*c?pBT%RwN=$u^vjOeh| zy-N+1b>Rlpjflkp_%is9S^y_xu7KZSSpgq|8e6P@@105~ss1%IrF8+yTNZkF@N&KaKIh*> z`T@!V*1(UU>fgl{!6PV$mPPQ35V`##xSNWESOnib+#ZYEFR7r>`r~8)=L_1co9V>( zJQ&k19A3^v6})lKiOPUB4PYe*Rg=$Y?tCa82$UWOYI6=;5TEGO)4Oz|TR+&NpO7q0 z2M)d&x<=nhR>d!>PeCC`-hjpJomlbR+wak1^IR3$L*3*<-XN{`VlRd$GQx?1r~$pY zv0FE`1&z+sB+QhMqln!SqGrih_!YY)s63@T`^o81kl@cWsEB)x7Whfv;WE&?z$^fm z+rf&$BCpsbQk=lV^Tl3m(-%-V7@zS^bixAI_OYiI6_d8WTwMMhzqP%_%#YkW6yq%NkL zG0}5N04wpEI<-x2lBS8YTKv1zy#6fadBwpCBsZZ@%a!SaOr8Z_EPMjfDj+U(-tJeayHS3*Bg@zvqVk zV;xV_2J;JCYVG@25;g(Ph?#0kx5>$BY65Ap`eqmporF~Q&q~Kl3rT)_#(6y?)$<&r zs<|-(x}<)Gms9(?gl?DPnzCao9`JX~DRA}))vT6UMm2dn_W=lz7Djouod>?1LQy@I z_MCDSlwOEfFstU%Hh)5`!K`~Q&2~iEvkUiz=HB9fq<+mSP{Q*NZVmgITrU$H9}oU=2QkmDZ#iP|H*fiU$LH7T#ohXr8$b9>#kO&K59-Cc^t^46IlfRN;H_AcVPnuvOv=!I7w8q^qpXh4DbAO7_0je2M2c1u4fQmM~y{;R7>-((;w@*Y> z@4x@D>yC|W5mBwW^2rxYt?XZ-qAEvJE<}|J8;Gbb5K(&ry9$F-=i1 zQFk8##>p^`yK$NJ{N4<86orb9`;=V8z;wLNHBp2g_d5-iz76MMtwT574;t@bhfLb@ zM^vYf_b4j7;jY3}QeI@Pbw*Hb`?(1ON8k4-GVKA|&FnV%?=BJK5aD3>|?`+X2?Og}ts2TcG^frZfiBa;5( zfn>~+Ma-9onA543d&q6ksixjT>UWsMK%XJ?1ZdhbzBtoC<$N&p2Ve(mblZS^dDpws zo~uL;h^i#Y;vbQvs9=cB$A^$1nkF*9dP-R^UgyF#9xN?HzNKSqf_5^D?E%vU$5Xw0 z4Z{0lqv$TCY^c-XHJf-;BC6+!_4J#m(jNEmI8lpu@F?y4$w%ROj4}l4+-D%st*9A3 z6=FX+l|syzgf3y)^K)2|`aqV*ZxW&2EutIyQh$4qlCR;)wtQkpLjBi(@wDn1#n-tW zqmeu8P2!Q-8-!h9mSB7-nl1F-U=pmvEO4NSD#Bt8?GK~jTZuNMu^_50bZrWz4?fb? zpl`iQy9G568unUL_+G4Vtc0DClxFJJ%_RM_HFt_faS|*D_4Pvv)k;NaPt|Fo9S6{> zbcWYZ29)UNVEG_7SfFP}pAYG1TS)q(0%=bt z4D64M79rjekJY(~6Mf$o3gk{jZA%4FI_mS}1mqh}io4_1JU>*h>8)z&KO)hzy6VLx z5-{#0#Ia1*R(H}r-OIF<-J%&R-Z=!5fXR=vTjsg&&xQF~Ap~d>W)~uR zgl=Flf@U}=w}yH+S8flYca5$@FIDuIH(d(fijR9^jBuwe9LSx>gOxjd3&!j_h$6&4POjllFM;%;ZSkcxP|DA!&p=vdmt9GNyHh&AN-1=LHd#xdBx9F1fP z8oJ@KSxP>L0ffiu%w;IteGNzsbbF<1q{3Q>1Xm+~D5Z&ITHT;ambdu09S%q&>!4tY zL2j_1kcwxeHUZTU^sL5BA5Ru{5SHn)KpXE-S{0nrx^3t9P1<6xxM>?tR)wjno-w0R5z*OYRT$U|fDi?4v znpwt~MrWwRJ$Ylu{9?uC5S3{3hKI*Xkf+m-7o{jS`LLXKL7wN%zm052^2kr9g`$%Z zvL6W-QOku4aW6hChAM)5CqM1!Mt+;+OSQdkrG9uvmbmXuJ&3aynnt7NV3G!@VuZV{`K{tjnpJBgTU7A|h>b2@UkL#sj#(8HNxEob_+8>{p4+oORyKjxV&v zM{sA^7Ap53wRgwMji_(*$XS1>+y{Dtx9*h8@6i(u(9*Y6D&+r)O4;YzSPc69l9 z$3*@XXz0udG;GTWlzzIlzyHCZ@#!*u2W0x6O)M)rVVl-i4o@J-zLM$VBd?Wdo6E*K z%g*&VBQJ{cESzUWp6oxrsD*kpNl%oLKhbhpFIwbvEMP?8mPWF^;$&|7{dS z%T&a6#B4tmVcm~E>Y*5&gW>ly zuoVRF7aWh;!SbHQk0(&QReK7&VE8?ajRMXCG}EW%+;o~i+Vlw(9MqFnBfv6D8yxdA znt~nTV^xIf6wU??#)`1FKXMM5$oZ(hX}`4IFo=CZBqJCPIR}E;!_!J}EAkdSdyaZ` z$5VLLK;4$R0d*v`3^Zs-dnQvuLro}^cIvsvXlXbmYcO9vZoqFs?j1g=uTiO$x6`d) zJko)Uk{zi>u)!bm5ZT%fsL2l){|q#Axhd`+o-C7dp^RH~)o2r%Zq6+ zNTmiF&CT8IalGSVtWSuRwj4PTX-~brG>5{pAzRu~cl{{~+TRZCQ}m4oh*-cyV7LBI zV@)Ea&886X_3dfT9vaMWnWUn!INkHpmx<`uoO zllDyalC692-jV7e(k#z#2^^}g=BXV)VpfdwxzN<-V2`$uI&ymKN}-M(f7Fdy^|7Df zA54-K?@U!al;da+5Mv851fuSLc{BctYEw3a5D*92kc~s7Jow~6?%m$xl~*KJkN;U5 zsD-Efd+_&gI1u09RX4UaLzlGYPSkG!`M0;avV}29`$Nd2iAPee0Y!DkC|caBTS#j6 zA7?(?4h9pZJ@fIrd@x*!zS+=*37Q2X=|v88MD-jzs*s~Mo#HJ zN2iiUzbHB{1s+Q8r7k_)NpC*EdGJcjm8jJA4d-|I7Ng7Ols;$kfK2;R_z4%-E8J zio0=dc&g~MUL%UrY?s{GqBTSjf@JiS!k6*PxnhK}g=U}|_eQ2c-WcP9{?$rIq##;9 z#t}I+T0hniIi+}Kw0@jJ%sEGn?!Q1i6dq4u!li$3(%r~edIxE7B>ux9lI+|X*?#=t zEKx6SBaXhGWk^}PSKAyKM^Wg;mB^g+$?y@r#siTfw9R`P_B%WG=QZr|^?QKAqqipT zd_R({?&R(9KmJAfV7lz25`W$^{*BMjF6FXVbq=<0o&)F8W5+p;6An^l94a&R(+1|} z;p~wU($B)_&@&6aX1X476tOFn@%|ewjoIkZQ4t?bLF4%-KIAbOiAbMZI!RPMjnGf+ zw~x=b=UCLGtz9T?4INY~I?%F;{*dXPa)Y-QSxqwn&dAYQ?t%1W%^x+>XwezTi+|g> zX{WI#@*XW!3{RquiHt-1nBfsSk1#67OEcKR{UcOE*uy=ZRLR)?j9zAVjL4VUvf;dF zlFGYyi zW!l3hMV>>V+i;iq3$g67(%#6q(e-V^>HXVC=`Ax}RjGYJrS?Ti?c=fR{zkEMz70ZY z`l@Nc@6e*Q!B<*Q#k8a=y|MDP+p^no!pCGz$-@j{|9GFQEYNHZ&0k_k(GKIdcpTe}~GSUcH zir3Gc!p0g(=a#bANzkLAHyef!3gp}tbYheEK)M&rz^`Rn-G)d-{{=_!UZLz_B&hll zFVD32viGRzo21NN=ron(wCxprjIKzeo#&8=k?5z)&kHo7*_5?~@cO&ooZ#qv>~ zcyxZ|BZvs43YxpFK*u5uf1~ExM^VwDqy-pf#ZrUqf{r;9%f;<`a>`i-KLcGwc@CtghzQae) z#-~kxI0q`d08^W{Xo7ToD)rjWFu#GB(et3saCSFC&6m*2LssskL+M}`3&gqO(ThX6 z!+Ggm<#!mXM-c-8&UjFSpY}^SOu?%a19;JRrrtT2tvkE)J%_>*A>hxl#t6I8y|Nsc z&(rq@qBCmntRwQR1$x7b&kz!dy%8P@(Hr)Ra-<%7Je^K0MZR_A&OkUhPhfq%?*`n= zXecU&cOGoo8+QAnGtY>efPDb#&g~NmX$E@A|4c1_sr`?Ty)n0|_eU_`AbdVZVA%zU>S2JYC()yD~x60)%ZT@0#w9SyDDPKu;7BFwl`Cqgs`wQH;CR%W1@q;Vd#JS z4E$S$cW&mMd-KWZ@W~bDof4Ud%)JGFoKN(gN5Qj5(A=h*Pj&>-Pap1 z9cyF3DZP4W&)VXO>}9kpWs$)b%D`oT@g2`Cq zA)WglDldK)&c6?TJP`WBcxg{RT!r$2{Px&(XLRO5yiWwTMd$ApXX0keMIFk%VO01q zngEO5lAXBuz_N|EIL}>(4p0BPY`#V}l4aUoFfq8kRr|}LEPO9OZ+Pnqzmd>8Q={}P ze`#6r*Za4wbLt0Q^`qgztFmqSp11WCyAqd@3$5?gr=V}VzP-Ho6@BBU5=IhbM#XdJ zM0C{UL;2#p#fkFb1Lehd4Q?lF)z^&t_OIxqz<3X_crU`>@!>$PBODr#p-nupJ91^S zzN6FkAokyCn}0T*9xijz?AV>-J8@p_{7l>Y$oOpn9|Ue3za8g(XTtA%soeRj-}z;k za~t@t#y=tW-*NuP_`iuqX=3e9^oz{&JVDF;h*wUnei!S&y*SXhDK(%-5By@pefyDc;z_* z`KRnGGhX8C$ugslv!{(cnFza2_>)tf)HimC+=-!Uw^7(p<(Jm*Gg=Xft#79xL1PNV zAQ&r81Y?*VibXomKf^YNu|cRx)hml=n#+zG| zkv>3eb;gPV(nuep?+<-5*ugS*DIb&>|K#kWGUGkYKEXx= z^U>X;$dq0E*h?zYS?=sFbM7jORXpd{9{SYz`4$nNGd?!(m`DKzmfAyy^v?IsSdkXD zKA#nz{!`~Ov*TlLnDR_~>|Gl>pG{}MV+P8cgJsU%GAB&8zKvF6zA;8|}c1h_(NZb?_qWD8>4! z4@=V1zWJS8$5z@dd1bm+J#W6h`yT#UFJ`Iir-Wz<<|Q|4pUwFn^c6p%kIRTD4n3}8 zi`7Ilfx9r@xl3>OG|w*doFvfBCh-b; zhiEGBmSt)m-U)43pLB*#K+nI2CNL_D^HKSlyM3^GimKN(^d*o-J#g_}0qz1&?QKRg zhkivq-WEg2s6n-b&D_}15=eJxO-sb($LLC-AwTRGG3O{6ivLB;EgCD@4;3)}hL7)v zy>p-8`zPp_VQ-wft^ldi8fo}lytCOKojw)~;On@eDUH%+BJcJ+fQx`w(`@J+MAH&3 zEZ%A6mkR$U8J@oM^KKx1G4@+^Uq7n<+v0ReF98UQgc8EZ1dQL^GEC&tb2Z1S{ z2J-OY+ri+J9l^XEffM!wPWUuXx+ju{^-4F1+!I6xu59genI9nXfoGy9Rx{x_F?5rwAI+x_nMBk zxWhG+f^?$(N{EV#hQ}7~?4L-E8@pKf>y_Q2jfeAQ`m0#c-IhA_FUnb;a(h{Wgk{x*TdSF z06Yo0(~R$L|D4euHT_-mq0K$Am|jBt5pLUxS7^I+kJ?(9p5R0#e3*%Ep<&c8TDkdcH z?H0Urrn$?zwFzPahTL%=HVwvST(>|h`u+gVVh`XVM1{|Ky!9Bm4#=QcEFZzx zswVo})p@~KO|#yxz7>;y!a`IdVhXP#j0Ni4YtSN?RvJg8lRDGC7a_Ly7m7~|U?S;t zSuU{w&su2vPDVH}*$&Gk#H^tDf>uT87usz{<1V^)7sRKdSj&BE{YYqq6CccqBrB#I zL>6Lm=mZ3t)m3&@)}za2?Z`Rn{l~G0g6?D_3G=pT6E=~L4~=&yfqy1~elUC%-L57Y zDKs|0wn%U@`rS0KlL$^32$rVSmLcukScIL55{$2OVc&#M0LnlCG{V1EVbSVjU4QEA zuCl4nV)l-lsl!_Ie~+pz)G>HI)&B=thl(WoAJ|H>N$O7OIe}}s#jP!ni8lI5G)KZk z@Tni=BDEP+8GW<|oBL9CDVb0`L6ez%Pg1W7af&Et+gb!6=njeR+k?BpdmeZ~dC!5v zhO53iO!z8bzjCUCbSkW4oHtrJ)%J(Uro;0!_<#lN7DvrAIvBgf9h@?VZOUs;q=8e= zDci*&RJj4?KB{(#6O<6KMHaP3!1!1WX;M!^DjKwk*amn16Xy4fMEi~*;pZCQN^U`{!mgO)WxeN?+jWqd9^d<t@yMIf?2#yR=)sfRhD{ zzfs3x%I?TXG!UWzlc;~cgf)WB542m0avYAXxh`klZ74{=`1JAR+UC(%AD$6865p_J z?$K^N79p0=9?ltk)Hk7T3FzoxmgPF8qpxv01YzTQMf@@+y619(BSg$~ZbevhN(N_y zx6DQF6rb#fQg0^)ToGTC6)61(Yp1vf#4pRn1Ix1l4PVUAHoZ;A_@rXWKXel3!-Smh zWRXQQ8Wepd`U}|TE*ymi&PND6y)97sLgY1-k*C9I&Q9&tn-B_VbBJD#Uyl0G_-x8X z1waExj2$sZe5Lpm=vPpM)sz!x$>B3>K74`9W4s-7eyH6#3sMej!*U#ber0xi;@Pm$ zCEDghXYVo4d#}H9|3rV@HVj#|clM6gHb2|B--S!#+48(+vE!`L5veFM1`G1bj8_82 zQ%2{ruLX@)(R`jG%>N;@*BU<+Y1j!}v&x$0V)yICZhgmSK)Cl;_P=6}kk8+6C~NKH zU}?A3(1K9@&bRZ+nqcE#9Pbt2UZgl^B&hnnR;Nt9AEHEl^j`_6HJ%LvAhPWKyG56y zZ#Qa%iqh`7i~XJb?y{zZxlUARhqT6<@Ek;D`5WFE^rOWLKS-gbG=+1s5a3I#k^bU1 zebN9@BR`^Vo*V_;(L0&z?wcj!$kBJqbwfo*-!}nd1_|5u-HJ%z84FKFPNKWBQsj3G zAp`M6Ipjjwo=PR08QuEov1=U_dUsP%C&(NDyVv>9U% z3-%Anivy3*MO0oqD1z0=i?QNjnY=hkTwE?M4igt2=c0Lu&+v$gnevWTT%0K{V&dXt zap5@|7mo`+pnvdQ9kOeMM@8v2?Y0#-xgeHvwyvR@w_We-KNoH=IeS*qB=K%{ zXaCfO*JdiT@MxzDbGnsb7L1-Nv@$gA#7?v_>_R0r$;xt#?VbHcTFI!+l)IsqVjP`) zL9FcTQBZ7F)54>%UDc}H!lO|h31p~;I)+$=dWT7tp`Q4<0aFhjH2R8qrIp_!+M^tsCOh&?N`ifbst@nCbZig z#K|nwV`uw~7yX^@XW@M1Ol07x6X@)0XJUVj-+14jct6MQdJz@giw*nXg7c3;kogmw z2s8ieEMMY{EWh!BKk?ouzw13z2yN6t(&aPZ~Ricn9zvL|Abeb=|o4U;Ece=FC_nw$+HlC62gBj`K>0;2G2P|pCR#eCeDGF zsStBWaf?l1oL_Woo}9q4-ZcY=6&Gr>^(A&*B!`9_&Z;7SLAIEXiw7j4D#m~ z3(rXfI{UrL=w#69TCLfb&Jn9?U$>FAje|Bb>L(Tm|&`&mm+JxFol7^Aw4nMQcj#T$3sSt zS(Ojz79%V$W2Lo?VI!2A_!wY|5vH2_*i0jwWb#P}Z!yB*COq%t&HoH82J52Yi`R7r=?b6YPZgTn1Jy)x&k!pLyk-~izdw@2uyEB zkDV+_V0g7aS?EHHo$ObvS}>Y3$N>}eR``-Y!{5H>eCwFbS10Cuic&Wo^^mJPuiKCR zYu%`F%Fh1Mk1o}mrn0lsfrcmWzC;%~9$)4JjeT0fJT&Nif2V;>L$|a4FxsKoj~y%B z*<^lqm*3@Rx;(EhkJ6Fu>OT=VmDN89|7Q1NdAutJpK597%BAPJM$vO!qsc_>E*~~2 zHr1l19YVw6K+5rF7VwYQJSE;H?#Lr{FR{bu>@GSRLuYY18%t*mbT$tE^xxbuo(@<# zrNinD8ddi%@0dV`>W;(daCyfObhxC0-U#l$u){-#vW_F^Fr(urI-D(9ss1xMj;5=^ zj$`O>LdUUmIHqF~9ggTYjt*lxj;BLz$7CFICwx#DqpWEK5`_;>?{HG0L}KA5)=h5c zOMLea)C)K$z95kH41R>pM%*(65FaE+ds6cHcDjbcEdAo9vaVK8#YbsVpcMCQNe*ucf@y~(;Hcb`D%11 zmTI@YjGNl#?)XF_K6Vdg`>x%yv@nT@9q8F~BVNn$2!)hxyPShWid`vp$>E^vKxT@JJy2f7pBX_^7IL|33o> zBna%FL^(<|Xwbx46D5_@pczPDkIpFGv1(1LQfyU_OayDuz$BI3aVl-GwWk;9xAv6N z+7??yv|bXxB%ne-MG%X@3(h!zc;l+f@BLYO&twAF)7qZj>-)zSUuO1RdtIKj*0Y}V ztmn2?R9jBxjJ3&gXxNla%j0{OKkI)ee?csFU|@EudKB2T0T|!7ome1d0y2KRd-pOH zvzIH+GQas&J)ogrU^(Znf%zb7Y|x)5M92K5V}7GPG8IQ!^8=Ch`x+q;T00{vlc(Uq z>>54a3kbr8!RT2WmtmUZww2cL#wu5wi+)#FotntG3CF9sS_rizLztq`A&iF_1)cW^WlX;N-F%-utceYl3^Nr<&YOA#O932Np=3jxr90Q=uiUxR z7tYP^OhPDe6x&%-l1n6q=u8BxHKVC%2{*~hq%S9lAyX#xS4w3u3&;{AT|G|J;5ZH< zSJ17F)X39zfJ+%;5#-$-K1IiuEG)EIHd4VtX!6k_3sK7~Iq>iTDu>Z3JPF*Ia}(eE zk83domYjd(cSo;#_U2JNRTAhUu&W#0{9!jPRery-(qFc;?#5T|pahb*BmCc5cD+)p z$JPd7{!hkRj}5<8?9;$p9*17Rl^|fV7smGLaF3s)7u@6HhbmMymSP@CdnpT$2y)?JKo$5@y#4D=?WJRr- z1#jCwi0~{g41YRjtV*7fsYc`1yZmP(e5U+CIKTb2gK)mz?jD?XJ9M3O_a_kZgzouJ!aq6|U!Tl2jsDQi0j-5(dR@fJ{)Je`@(f!t>94>{;{p{6)i!v?b3wj$c` z{LaUb{l!+~Q=Vn9tJuX*FP(8>l~0e+O1K`>R<&4l)jBsRR>lAkwj~>0KJtgh?7Q7j z*wIORw+i!Ou-W9aQup;-KB(aZ1kV-J4K zXx{ADY2UpA@xD2a1!Fgf5X+WLYKWJ;vb^t4z3i-q{O7+IPc6fi@a16ak&=3_nw=2H-R+V2KXxr+QfA;b4*BhrUsl9#r zb^czZd-j92&6KwbR;m2Gl$VPLoVXtV-t=3~TQB&n)nbV9t(8`%wL)80p>t%db7!t| zOMb00c_0^2I2RyaQh?%x#l2kSS^DKcmVT`0zCZNKdHNiBo+>)t-KefO+kCiQAGFb? ziVFBJPxVA+^#vnLPCbJ37^=vBxc?Hcxp1pFDl*~9B`4DT1-ov)AXK`j?u9{1l^h;{FaXEHV z71oWUVkMQjNgx98vbU)Qg-fWX&Z`I$wsjK9GG^ko^O)f4a%bDVPGd4ZgLfi+#`31? zffb+kEj{SkkFP2#wG+4nSWKVOKF*r0nS0#XD(1P`%bMl;Oc@)90bTnp)wn@i0SAID zORL-1_K294Dtd)g&ek?5%R$Y=YjTzUv$rlZ9pA^c64^c6iaf<@zbFZn)@2>wTkA!g;sfuANPZA5>>$-LCr|%|2#P`cX5M70GLqPC@WE$pSfMEAjBn9 zwY3rDYvtbGQA$xzu#0(@Z(3;M+H+4Q7eo<7V8HrOYfW=JTt|>z;ZM*xz<9uocxJWi zqw5K=p=8u3IOh-SZDjB^sZ?nDmuTQZ*4X8Sj}^aAY!&7xv<9o{NwWqtbmao36uZGx z(Wwcb6eq6|!(?QFNsc^P?Z}q?VdS{3Lw1HmXvZo$wbV|nYWx_Jv;662p;OA1zw*5u z>1F#^{r2U5JkiGH@qa)5NB$OBnvcaA*5X1?fTeM0k<_(wN70M$9kQ0e#BFbW1NJS+ ziP&Jd|C(6pyX_Glpv&mhUT%3#du=%_)|S&`EpdSPL!-6jv|3wEv$c3KQK}*P8`z5D|4j^MK7BI5{WQ~#%{L?YxXv2! zsJ=3QhU(NPm`lAo-bnf8st)jEl43E;w1$X`k#!NsiJ#W#~3xm#*AC2GsDYZ zr!k2L^2*+qDteQNPn-Ijl}=nGY(N!2c$)egUB2)g1sX4<<)qQ!xFPt`5EUATUXR~D zugCsI>Zr8s4KYAC;Ph`AofEFc$V($p7>dp)4@IYr4n=Q(6jbIh-bT^Mc7^}dUwjz0 zpJl=l5NjhHj4lwpt2_{$0RL<3D_>wDOc|DbPp(wAf9C{PV`xL=Z*TUPU$<5al5lB) zD`Bn1pZg${BH?EOM3n}k^}|fm8_G>nIo25?Bxsrm7B-EY1>WBBDR>8r!%Zc{nP3pa z_Al(u{}<|NA>E6`GE=~f8mo+(8#3gp9&)mc^MLw4#lRtsqCD<5kXS8)w0SYo^+EtL zRK9kT2L`;mVAyKZk(I}Nt5>g_Wr-L0(8GEhEN`AEdlhsk%`6R?e=!t2hm+d{1;N;4 zpMU50eDrt3ds&1nz-x5c9lxNQg-*x}d8{&!1&!0T$k)8WYWV}%4QIt0}>!Dx#A$I*rS zvf3Ekdv%IRk8Zv@x^M2#JX_5JXl{|O7ktfJoCa$OH)`{zJbC=Xz6}4w&fuSWf!i03 zF7(FuO&F5@uy3KSag#etXQg{(@P$b`p4p*S4}-ytPZ$PsfBaftaN3f;&(cqsj+!oi z?%w_iDS+v%acS5d--8HCXd;7$9z06Jb?-L~TuxhJM6d6F9OjeB2Hd>{sO5DK%ME!m zGqVik?pXsN#TFX-ySwsJBMaZ?my@;i8vM)tzGL&j-_y3t#U`{J5fvwxEk65vy>1*} zNg4!L2c56m`N;YDB?7J~ z@D4eR$Jo(aB0Fae_N%946^|@0bVCwl@HdP9G0xY|bK#r)c#jsf8)pwoPn=0D8Rg_7%*by#!$%B(wWyEb588~(B+#m&R1%a2-b zj4mE3Beo_ARxwTf_S*hF68qrpC7VjKs+HJh3;}Xhz|>CXsv~!gFgEQ+(3Xj;WVN{4 z_%-Ybvyhrx!_>yvda!KH_`9;t9t)Sl7W~k!GF$M5xNvXGoqqG-I(;}g0p(e4Z?R-Z(g6y~1*9&vPM3AM*4Y?t-3 z8$GyelURmb@rUQ)Khz7qh8b=eW#B%0c83mF;Lxviw0WwDmmqdQnEaQ$*Kl;u=b|=z z@?mchoYJ>7JML%4e6|+neFHY8+84e6Ij7MchR-%jRaSi%bH8WKyzxG$K?Ac>s<@%n zSkHwJ3n)uE_4I@U_Hk#i=xg}NL)5XVI#b8=DXd)NT*$>E2FhquRbyRfN4j#R-(@@Q zyJNlrL-uploGdS8T6-dY$g#=?2KPSgC<;LcN6w%cLnfZ zWX`|^(GB8fZtjOT{;!$>F!TVwfGZymC-@wzu7_vHp3g%HeC+50F8Z&BWK>x#n>c;C z@v`93+TvfbS~idZpAn4RRTGT;R#;#y{*!?qdbb$?>%nCMP$CYfjh(uUuQ`E&XKm}b z0FsFI+*6zE$ftLOj}64CPqkAlgLm!72X`rW$q6im$j8$npIS3cVzlOitBlqSnbEq~ zoetemyCwc54%W#l1I{mV=y}NbqgFhHt~G_M=G6u$7Z<768v`mLQ#= zKOSDowp$;Xy)kF|oB zMH6jnB{6{~+14s-lkl&f`@w$Koey z1fg*<#=C(*Lhzm{dS+w4oWJTzFm_tQH)!U#9Fx(_LOhM0x1GGDp2NRs$=7bVz4nIi zjW_$B34d+IC67;OxN)+2iy&{t)SJdWb={5Oulb+4dFu2j{->|IeddLx{+r7NU&&9jRGpZfKR}Dk52Dx?-m;wK&?|z>)e>@+=y)NYXg-p-?_E0*13JC;~(Z+ zG+aVH2CesAHsNQY6l)kQc9o0G%W_@}|L5wP{=RZ;XX3^>^hL;!7?e-vzU1AVyy0$3@Gf( z`C4zdJETTFue6>7LM;)bIjhV=ZkbfkuX%t@#ZLkJ9`Z6T4ZF@`O=LOnJeG#nxQ*t{ z_$Go}Ux3w_5#&bh0=`Q)&=n@D<>U8H_iBI(VOA$nBX_>|_j|QY--QG(@St8@cBe#0 zwTv&Z{anGVWEZi#sRCBC&WMtwtcN67l!_lt5j(o1SV{6~dt48x4y)-2Js`w#{%XEO z^Xi2x3Jau=4cGA!AOA&P4s3R=WIcH3$vc)UvyhFFgJ^{vJzSoTkm~Z3k;;{eZjLr* zmBZQcB(khAr=ONb)s`asl$vzi*MSgcBJxb|N4l`3Cepa6iu zHY1@0*XK&_-a583>Wi2KPUmnzMhE38B`>6bqKod+(BQ-ntNbFOM2l2d<~I6(=V$1b=nC8gF7LS+xZzu1kVmN;Fa!Kha|r*RJSXXo9bA)miAf92$- z2$wceAWt%FiY4V*!qXwJ-r=|}<*mnVDq+byV)$Gwhxx7c*_CCclD7P|@ZibFO$S4I zE*y`B=!>SNRMG7OPw^_b!2lrz1dtcIxh0-xX`|29W4z5UVPnqt8m}e_52jF) zBcGzwQ2-+GV^h3Q>gGKdt$Y%6A{HjTTT~s0?8kccr#$(e6m|q-50xmN9X;)#)zaoN z&P~Zd8h>48(Cm=Y9JsdNQ;|}$GOi4a|XTA=)k741OgU3e#Q&Nt(yR?C2F#P^> z_B-6{ht;{+Wh!MmcE0I3#}0IYO(f|bfgQj1L$7BTZd4)i0@bl@P+sY_8EoIUrE|5>jNLUD^DS zX-Y1;r=;Hey2?vC_GHQZKm}62rY^`rR`E4%QVZh6PdA0|pl07hw_`6_gtzCkO#|4w29i6xfFyg;ymXlSxLCltK zhzu|m-PCGg$;Ws8Hb;SbTfWBGTJxYUp1innB$7?#c0ohFV^me~ab+5ghYaMw*bV*V ztBsoHHNaCG1!3E0gVqljwG`-`DtZsZa)T@wKU?GntOn^gCQ0614-(CqrvyFXF2 zG|#M1kx5~lD|qrQsVs~?04Y~XEpMo$%+1VlV)n}yNvcW281HBUL0p1#=hH6LPmqRq z$oIBsS+u5}5t+9-;Buc5G zW;4?}h>j7Gxb1rBA{qE#)yF}QXfCC#y9WaTGO>iaMj7K&QQmVN%?=Z8Rwj*1aLX#znT z-$8`!qF5GTvm@?GFw)B>-EKSEKx*Qgtq^X-1I{)%i5^z50*+-$;&9B1%|ik+U%9L_ z(Qm|}WB!0}0uX+552a#xH_?bIJv{|L7%w&}6JEu;?4bn2)rhHNgIn@;x8zq2D0vZIJ-l3 zk&1YClNXvnd~X$#FK@fV4^7Wt3&E=RLKLCN##GUQm8#lH{E-stQ$^8qqHDeozeDME zs;D8It{NsQ@l4|1WhY*w#A8!Mf$YR;C2}#qC@(SU-djk0z}ACIgKa)&4W)`s?hsV3 z$NzjQ2e01pQbS5~e%xyt%L}gdIZ=#}MoH^B~je^l{zzJn?z@tS#dq zHXtbjVtKy={{l|GK*#ue=@V?0l&c;X04%m=nZmDTnq}7@wz&WIG<4&N%~pY>L&vz$ z`kMHZKQ)i~lKC}{_D%M!c@#r`dWImukfxu~xO(af-=U2Hqm-TDTU~<|;$zty7Yb#wQIY)xR^$RC6pH+Y@4%2qM^_|OfWIzjvD~Iu z?gZK2;4b|JXi0~FVb@vCL;+7mK2ECm%|+zsy~8<5lR`t z!;ra(Uvz#!Vkk`oG8R0+=(*rD#y+jW;kC;|o)L#?_nD&IdZM7v)}xo&9!h3}>Fx$= z5Jm7PTm0IiLA5GGnq1++asrQ^bOHU6rU<6XC7|x!D?VxgrL0o7YgXy}l2*OL_SN|G zdynCV#TSb+6tk9nU`k9tDX!r(r>cChxA3?eg3|@k6$o&bkDTxEk@py8P5HWMu*O>a za;6_jNEO`%ZW#kHgYc3Z75%l-Adb#yWMN2L{xE+2HlQ$sfIBr{98Ko$E`|L6k+nlJZSOhjX61_;Urmi{Y@=@XrI%FTW=7Rhc~S;D2Fd(v zGSmHd7f!Fe;GOnDHoQYTcrOIrc~$=ay!oF6FWPGtw!}3IZ1xPjKpQT6jBX7d1=naf z;}*?fy-Y^l=X#Mc{6hGDP5y8%4FHMc4{tGnY5A*SdC%Tzn>FAHA95uuSwnY(w}k6`=m(z~3*;h?1O<=={rsYC`JFKu=4G0Way_Et?_ zS{|nDB3Ai_h=-H926m!{m7Q=Ip93o|SM4wy6MN8d9V6snoIK`b9RN!v8$j|gM=S>X zv3fGyW-?{YMfy%$FSOcNu!NlM_|qS=qA5De1+PNGTdbXgJ@nF&8exPhdFZ`kETP&Q z!?T&iGWuC_Y&XwuF;2m%Zk-hK8%M!ZDLC)xMEvml3Gn2st%Us<_vPHPF z5Q411EQ@Zy)3Pwjfn{O(aL}^Q>}9b!X>U0mN}UhXk0PY_ZvPwyB^-$!IWE_Yhmyr!{| z-EkRwc+ci~J$PZb)z@Gj*s%JmlP{ZEe=}La$ zR&rBMC9sw`iC<+-o$r@-9|Q0@NijT8P<1=d+y9gqM-UNuZo=OL0Zvzq{c@~YW#TI zM8VRtDQC^zLS@=iI7eMyGSLeghjkgM%e4sdB*bmLlwSDFO*wCQN1HD`ZWx19(dED$ zauOA(kn_Cp;%uRi8Q!-6QU@gITo$lW(BJXwiPNrC*WsuoKnXezmMl<@=m^uQ9ks_m zoE@%bP+)aDW|vU`x88{>xRlnKS#-(k8K`wch3lE@86xDGi1+9Mll_p^hdbHB)a0R$ zCO3YEQaz`$gN`Px6wRzx)MyAQ|o@PpKQ0Z7+0>abN+3!8&b+(V&+2YeOoz0RN)qo`v zDV}vZAvGO&M?W`MKBp7i8j8`q1^{t*jTST=ndr*64aJ4RB|Z|;a*F8iWo5 z;GiciI}`}@fH3VK5PpB}XMs@ffiTSzv%5QOZ;brKVh_Lyz`<}2?EgLk zrJA_zimxI>NO;7*lW)C1P^KF*nWT?0mWbjt$mGHAR}=YQ(Usj}(dY6g z7X5znJHKS1e&LJi&9AE=(n-38_d~JhN*6C8nV63Frrbfih%h5V+pd92mv)x^E&@iF z5q2N`a=_=WIpNPQS-=BZJAv&c_`8W7%0e z$vWqy$h`cC7b8_L#K@rniW0xj)U+$Up4){D4@25bUfOcfdehU12Z28YZa@MYJO)`o zH*@924Vck1a^!)Uo$r0T!e}3ju$a`p{Yk)ky@E6lZx@0>uRhWbG1szs1&uIvQrEa~ zbm`56`_#3~kFZ~HU;LQS=5;NvUguD0K14mqA?l4QpcY-FP1E0brj1?kI1$*$5s1v< zQWwO|yW;DV5}n1#r`iQDzMPb_JjA+0k z;z5XnkgtV&|6)9dghOh#&FS`BLU)!-`c_cj~p`%7&w3lhP40V z8NGUi7V!}Nk0#y#Dl{*?N$B_4-VXn0e3M&r&i#M(%l}LE%Y&K61J>k;f9YA1|FZq^ z25~Lv_$Jx*vGxCbuzhUy_nJd|?~%_$wiXk|o#O;M&-WK%MEV0lYO#$3ql%KjA-hRG z`iJ}oE&@qF&^Z+=2v`ys1qXCu4#4`u_?FwziTP19X#I^l(VQV+5J zyS<}N`{)g`cma-{d#o8>Bu;|W`~t{Ok?Iw1p{aUwj@A5*umpFlsy&U{jq98pn@G@x zH+I`)OT%Rp$;69r^UK89vnp|2ctu=iMYCu zn}}A0%GQMnxEge2sO;5H!K+#8`)>%?Y@5NzGpEQy&zV7Gedym<9p_Qk&iVV&OX^C)k)3^Wm!kyd<0FO zvfL0f>3m9#+!ABtVCcXZq5~50wepGZ`h+i%7J{PfILx|kwIDtNwIk&0@n3Nneiz_8 zpcYD9+^6v?I;}IkyK}8(onj?~8%D6+lB3$*D6}36mlPGOL+m!hZrf7IMKk$!!3TB$ z_AHmMme22ft%(3X9ws4GH1I+A?W1%Q8pef2gdK0q84!t!7@2zaBd1yq2YJ`oF?|dfOkf@qw+xooF53Mrh20 z5dX0M^lw3-|G)gFUxdtisxwI&@S6r{|BnB3^%q3ji?07>#((;!Y+4ZgoyV9D&)t~u zpKjtq+JE|ak`cHY|L7(E2VA_x=nh=WC_0_mjI7dp-vO@bY|je5T8cS#iC+HGTZXHp zLBE<}wwD1a%l4A?pPs|u8UN{udNm2s&SiOd#suu@pXooHSU`OoGH*Q}|LK~!-ziCH zAri`4{w}@n4S#A}DbTgmBOaUrpYT<)#{{D@F(s-Tdy+@OL0xn1AJr2(K)8K{9s9zw z-_UNo#aP4=_iTF=0`Ok+TgEnp1i1hpSG16NIY4Nz_#z*ZmG5gj)s7-Cj!vTC8e*f& z9G1i*NI^du@ja=$m{Y3RMO+YEGMMp#&pt1gWAq^>n#dkBD?eg7%;xDQaQM&yyNV0@ zCJ^6WlE|Ne_ zp;;ugljQPC2hEQxm@vjWaB_Y#ve(E2odYK4JSL}fa<9p`Xmn1_ynk&zmJ+i1f1VHH zP9g_BVAtFO$~E8#PO#tq-v0L!%$#im5``n($WTJC=Jc3>KIoDs0h`} zCa-PXm9nO<>@vK&C!=$fQ8i>w74k)ShlBbUBR`197_}jqk(_8a{>`0{( z{TKT$iT_G4aQI7}>~Vj5z69^oOX7EXUlhZGs1myz47{%U&we=!>FnhicIUCNh4+iwJ^1^YFMZWqYss|l7@mPVCK4P0Ew>u80QZh(3Xb#6Op@%XuDE8TFu7k zCw5;7LHnXU_UyemXaKA^i})Uj)yuPiLrC|czV_MkOS-7oy8AwT(yaX4MIG0bu8GbH zTZCKst@nP#KI*;3`z`l=i@o1Melg~r#}CS-L4P_DK_R+@R`+$0_iAvkbkM`zYq$IL z&)(|}z0yVwmDui$Z?d*sK(eemq@roy;IW%kqWEcW_Y)WS5-%_Va0h|NmL{%(Q|u4! z1@0g4p&f8lfr<#3FSz(;$6SLmn=6&Y8+~B34L=0~s5BibWDb*8I~S{Z!GX%I9>JgV ze63XQL^pp@Mc0xgh>CI{pA-(tL;(3AkZ9L}bSQ-gATd%jz>CO61ega)2*StQVzWa+ zzHtCq1uPJo+ItyKYQ^;m`6Bu5i_&RyYRE4rao)qMwQ654pu*hU;)M!1H4TC0NHv(g#H$H$n+1AfRpK0h z{qj@;_H&0WbQG{>6(UF)WrEH_u4xgf+Ik?;1WwT}L1GCi;>Ze{q-iF}yid~m%%1m& zdT;7^xAi`^=ePc2@$O}UpM%fqclk(#p3Z4#a0i)c} zFFsYNmzRh=4{)1M^9_urKQ`WHbpow$$5Uxwr|^)AOU`yhR}mSt9mQVe{zn#|x2I>X z3qGe2JXLhpPsmg1E*N89NO>(FH6glda1qeFd4wXl)80@}(VA>D`;Vr#VF0gZx%-i` z9+kcuw9&f4tLX~2rbu_O-x|WVAr~S{S{4rOTsAEHMO3fO`bhWa^!=*Q`2*E_pkgS8 zn>K=qb~YxJ`&hSrYw(;-D;(X3nU z)LOCOG5zq~ku9UmLQf8H>rX8`duWN(tV{ej{a~=s8%0Z*fHtaC`e&l+|2B#a`RDMn zbkI>dg`76XIp~v*%_GP;XtVnWat>-YkNF^QFXVipSY1t%1Lr+1Ba|NqaSa~*alagc zZo$}tX57(9+s=0AJ|7N&cKYnm)l^YFdS%RZ55_#hF1quE<4u0U;kf8r(TdD0H_@!Q z9&jGX!amgo>NQca2k*{CGU1iwhD6Vvq7Wn$G9Hipf3$Ysv_M6! zLB2rMszxsAm^_cm19GPwfPBeBJKxgG7K(AXc+R8QUVBY?LkM3dH#o5& zBdj^k@Dpg;o~H}cn|NmVb_NTy?-vtD&*`jK8`!lIVPPJ(Qa2otte&SNecCL-4nS zrf;#z8z^RuNU5T4g9Z3av5*RzSA@@n|8M*@P&FtAo6;~96G1claVad2!7DtX5m;7U z~=u7a#>sa@PRwhWd^3pWLMBHyMq31FksX8A4~;39h@iT zH&*%mD?ose3&93&{$W)}ut^Q>&4 zbB}y!B02!%AvnnqA2~l*h0nmd$kW#$TnWZXjtV;4?6Q}M-^T=ooRb31)cjD@#|=T< z1f4;yGlMaMSSCS$-br|R39_KdyRf8|MJNKGv7I|K5}%5fK*7s{tLiu!Q^<+4Nh zh=buMU^U5g(`Yo)p?vOxd}p+v_wy3J16`DGm_3)SRKCQj72Xf4Seq)E%2-LuQH*SJ zm@j;eQEJUmMo!tKHf(>nJSBP35E3zcMZqU&313T7MI8W1jL_(hid8nXavEHL z`^@e>d%5~|)w1}*<8ZE&_Y$;d+YO>P*Me{f!<@v%d}vZWzL%8$a`S|Y7emnp5^NK= zfc(Fm&)2#7nu(`#D{+X%JZ8#1PTAzmUU;44m8qg>pdS9o1}QsIMP(v(TJ?DsLJ$uf z@`uSc_GZMOoU*DH1e95H^X$s#ph!?`q7^em;BtQsGB zF(~g$u#!_kEy^9HaiS{2@=?KFhMZ3%n;y>#PhZwo8mHOI1)MA51-SFFfLmt}!UK-` z6uqvyZ3ohAH#Sr3{H$UR^e$G~tJvY`VpdDQe5kauieBHl=r-->nclv_N7GxYWw0q) zbX$L;E}qE`1Nu0^3+~q8a0cbr8DI2DD&?B_J`9aT8gqr4`zkN@VJ3HtmwQeocf`#d zc5~}Tb@w;9<;S7AFU{n>%*}n1o4diwtynYu$Md}0CuVXh1S|UOiwUc21a?u&%JV4b#fn+};Ry`EnH^9u2KqCQX3=OE&Q_2z3> zc+0jr@_SSfD|)@3JGO(A$=MllcE|tf0V9`*EF)uAhAI=|zi%1K33-uPlJzS`h$fzO z5}IdzJ*(s_BlN_F2*i+>y)U_#^h=)o0s-!(YON}Y9}?m!5PZPJq8^_(TCR8Cb5gm7 zVMrAv-2}YuQ$+2LRlZ58Sxc#rU3>~EZ}ck2V_$D?fpH;V9(&7RM#9Uvv&AbUUd8?D zj?>@xpq=7|a>Jn{hw8iA{I^Z>H)S=Cjc4WcCiQZ)OtI4`mMWS#7s}+tLFrM7IWOH}C z^J!4=>yWLQEyQ^xRdfrqTY66P9jR~~V_ipBpxDTc|3G%-^7Emp{b6)|ZWIg#10%#> z)psx*Z(ad`5Y;U`&&k~rKrlyge&cG1R#ZRJL7X=2C3slnTX(+&l`^9780@5ENrn`N zf%P#4S~}&FG7qDH**w&k6yoIWRs!d*96BgLrheUT&8}l_^k&XLaXWf*F*?aob2>&r zS))Z<=#`ON+mz8FHV?7+#?e>yG>BV(q(A$(v^uL{7S4<1e(L7RHPsALHLOsyi`}`Z zSG>JWkE&NTI~e*8x@D`L^NzZZ9+5?>Fzw$ZSysNXqN-@ZqsC-Vf(A@=m}q3+v1!GK ze-=<&YK7(oQsu#En^Wqh)S9#)LkBd|e#=IM6JAIGtL0{>uv#luYdVRjh0%H;ca3QY z8CQh7XqA}oCI@5(|b@1#b&6KBMX_ygYKb^=T6UPQ^a-FK-iq7WC6jBTVcKP3B zSXx@mU|G#N`xz3w5Bl>Iz_54h)z3BtCVoCyU0&G5J>qpnfS;2V=GSEsnm2|qEO^o&bNs?RaL}7+9^YfDc|8xJ zOa{+mm0tmxR8bHB64JSv*^7UHX_GX=5Syr+r8pRud+J7ve{Q}DctxqMXXxzcEZeT? zFd+kOJ11DxVcmTtlz;`_m-~#(MX05G51)XS8>W@9n*7EcY6doSyEzF2<%ThKj;u_0 zv`@jH)0(4;ne6CgrM8iWLgtUNM?XI#+WgvCPR-ZL#xq3LQ(oTD*$ zoE=2}`r9Km1f(ep#O@qc(VDg1tirL~){qHtes}ZB=F{2->$!3^p<=tLt?~7p%Y5M@ zu&$_K+G?LS)DYh@nIOm5cyk?z%QNkOXPxRM9OCyA2QYYRCHePFZ`l7D~1On8~+zEdwUtkDtAkn

    fYIa@eN)#nb#&>d3oHtjMKOC>B5&!vP)A%4`|S&Zr2*Nn%y8(#)$7XIPS8A$4@&^ zoIB1^Ea@MRmaI=+mCPfBLnH-bm7{uU9YL)X+md<7DpRNHES}Ri9OA;wAkhqA@tGcc zNZUz6ibRv+*YCuWmE$CJ0!;iq0yn7rKa6B`746bw8Z(%pS~$Ai``PnW^VwwTZ4(n` z9a9K<(MzH~$th&Tet`bA*x^dvVNO?DeDKIm`VuLxxql7>86E0UYw@POx%Zyg{6G%O z(%8PucjsVAedc4_R+dw-!)b5Z&izSkiNUisn{xM9Ub$9l@oRktK6d6kUb%bRa`)z| z+!|+<%B^gBckt{tOu6|-dF2R$^|!u5A3JltS8l#r?k59PZmF|QYWm7$*l%;BFC%;L`pro_yj1I*IT3FfJv6U=fKOy+x-W`6MOEe2VBewL8M zTKs{vczfUBcc1z5KM6Pc{`@h6nh%Upspp*aDz)K2)U+0VXf1xP@4&myyvHqdk6Y?q zUFQm7f|J9X&I8tgwfKE&@wUFXKRL76E!6B5x*MDBoQn0%QWat;qyc=y0Lbbwt6+O|>XWcXKW z@u-UN+}vJ3thTDQcM99KGYo^OEUUxB1^cRr*Fnv#LHpLX@ufb ztWDg)kN>G0IFgDL6|L~w+Gq0<-_;K2p7&723_X%R)#pqA>cNDEIrYT0w+q|e$S-)e zU@t$xf|Yz8^(DSk_ajg4v29xl+uq49*i~E5!7u5fjtrSAGz<1u$c{|+%~q^4SI(y5 z!?Dac-^qOsjg=Jk9K-{&KP>xS|7r1n>TI3l>p12gBltkn0*tdCjy}=H~ zF60`y4Grf7Vz-jAsUZ|Zw;ZTi-*90lHi?Ig4Ht)Em+5?H~rzdidL`2>3^)N*qEvG6?V)zhI6%cPRTNZv2PBnSeqQi zd4Kk^LIkD4YwpFA{$25Zgych%S;%&CdvE**;2PVOEcUl;E^OPJUt6%EU=6=^!TaEf zzpXppU$DEbpi55-?9db8hH49z)>gcVPR)$#D!X8v;VR-wVU7b%?P;HQLu*H#EwpEU zYSv^kfn`v|XN~Q3K$RX_E26NF-ndv1n-_0ntjKx1c;jqELgtGZ94m4mFQM2(Gt3cP z)f8fa0#&bT{!#~^5qL8EM1R|x!lT-PR}YOyM;?qw=Wwh#5R2U2zJ&R&dixPAT9KWg zPAK*bng?z6@WNmX)L@weMD|KBqh}IQZo()phru|Z`#I#Q&J>eToe(^efIpQIGWEz*uG3!dIYS z(XhRwCCbJAB0R`qjo}Ob^Bl3bXxBFp$53oqtmtl&)J_~J-h0}TJiwJlI{VV(G+?^h zlLuOw+fM{_uxM2FBI(p3A#pHtsG>TeD4)7hbhSrMue7UP5k2L{iY#Z&g0TtUOIO1e zLNS|%H4VjqSO9vm26{R&Lr)C}FyE(l8!BP4SaZURVa1BX&1NW(io9O2GhPEv$X#P% z-$+2!5*QS1?1`tP=N+@bO}dHMBwK>qhW>IIuuKa{I6bAwFY+0~$wG@~51 zj=H@!I@PMmkqQUsM>^%S9WIzk4+6pgn=w4^mMoAfdhJv zZW;I{;`c+j4E|nbJ8#Q}&keB|JvV;USvfiQcXMsz9Vj=^p2aHP`6xHbpE}%skqFnrAhPf3#sPZ0IkjL&x~-F)3Hhkf z-%2zHf$7UF$uo8>)he)>#n>q6q~vk>nGT1*PdGV*4CJty<6fEL?T!iLRqhD`a*(*l zXO}sM?8Cynne@oMyR11fyI_nc*>JMZtc-W&uW28H8ymEOpI~gzTc0o;r4;cmIiByy zQ7X|V$BMi`no4bPOI2ggN2wS;l)8KmrA{@ay7+4bK5m@}nRGPnE$33`P~-lp#(jOy zxL^HVX52R(Fz&A%Fz$alVB9wyFz&Bs#=X0}ZnGKpb!ObxYuvlNabIsc{pVgdpnbw& z0}{__|FUjbHrbli$`aV0cgyzN96u&~v%B}Fj?0Nfa&kURjX4%MFZ3W5U9|O+RAkRS z>xXTzALXRpPtD%D==hKMv~;rdUfwv0PPQiJozJf|aYxHeq9eBZXYW3inDAJL($egG z@A(E}LjE?-ZX?|^LYD6TQkGRD7k3tS)fDd_pfoS-{hOR?a}&ip_Uvb7y=29N7;QU^ zUG`s_ynlfw2YCN5NI}I>w+R0)ewN5SgC?!{-*B?OAX+Hm0;Pv zkgvmzh8E4mW_Z>Tq%zPC5Ve)433$phw<45W7?T%?8g2#*R@ePA^o#s?gJ z)A~64eFs?0?Lx)0e=suY9(rZRrr{{OWp@CARkkefRNCb?d_skZx8j!9fravcs(r4% zFc0_(hvYBpHv~QCYo|%*e=s_JcgSfARcsD9?}o}&h6%GyE&ZGjPZ z3a{j_&^Ra%Sq9VIUa0EuXn#FW^_=<}KCh?0YM;2kF6{PuAL7`fuBvwUVYU+9EdgHBy%FnYGRFWXu?uAp&-*+5^0 zD18hSq5DaGz*DP^bAA^WfA&pZs%-*)G%iTLqLWq{=X@o9Vp}`xHZ-S zEu#sp>!d*9Rr*e;3b)jSY=?Q@rWCeT#_Y^QbZAdq#Emyx5%~c<6EQ5Ip7y#|(zlY= zEwE#CL|dv`giO5Gh3_pywo6%MF-1wS$}VfNW3v|6&a8Q~vTv05mb&{>MZfx1KR~cr zL@)sQBM6T2xquf%yswMQ*GE;My5PaDazECWD3wO*?x+0Iluvis?<`Nu;PWBz0UO79 zW{ZoYnJla214bekJ(GLiOLEP0)Pe(Nzyy?Y{h7w4o{I5gGIjSJm%ZtG-{rJs%X4&R z>f&LE1@73Mo>fP=R|iCax`c1(vGwX`yrsSFbq(xzysYY48CV$Ux-JrWDU0fwtg_HN zhEzk}s-XwKg=d-}W#QB{0fj2R7?cR-F7n9*eHOG6!Wpal`L>=BA`*QMhSsMMn;j%= zKOlYwtp;{N)P7BBq~@b%I1Rre9@B(-xNS5UzTPWCX8m2JsM(RNlkASVxpbbLxK4UP z{Vpu#x4jOxB!^Y+G{PKyy%<+OXnH3+geYrtEb9DLtJw`8d~z^4y)Y1YHsAhMD;q{# zSH(s)0hhi+FGGE|Hmv@#Nz}CxaBH_&8CJ`U)Z~xW4li};7IHwZ9bP^clqKO*r|u!b zj|}I6yV~JccB}{=qk9Vvld3xqfx!;Tw{~FAw*#emzKN=5JE6I>JTDL(I2>x*%#<~8~rTy}S&C3}Jx&|FyHk#AFU3E>D)q+$%m6)Z` zihc$7Hd@WUGB0Bbxr7{Td|j9ABRa{+?rzA5B_n@3KYD2;CM|2RM)n5e{AjpRQLb3^ zS1~|c7sN`y@M@x98YoJDqH%0MyFg^Q)VfFv8Xr$es6p<|;Mp_t8%F8Lj$-+Y`qWe# zYCSJHYV>*0OGoE}(BRw-h$3^;3q!&T?C2=I;)Ku>rq^oby$hc>WW@Q7dCKjdoX(QqQp08h#gB} zr&^h#4)=3y8@yU4zy3ZvbWOIV=52pVOxN|Dldbv{A6U~?yaXq=nLkqpy=A^^+{{;U z*01I3T77+&KN}NZAd!orsy`bOJ=G1gnz>TaKsPX5 z-Qdq(U7^+7t+@oK!gO_qfBx!*at)qW-OzM(M}Ge5hK0uqvSI0}j{b+LdRF7ss&T`W z*-QfyH1!SsPxAgYAD3_EVfkd+y0bM{)fPTl@}i2J{-)}J)*9;sCb@G**mw@g8li8vkcxE24qQeLTPnhL(#0dPE-S%>zdyZf?LhcX+-dL zx6CD;A?FiTbHapjJZQb#t*I4jfbt${^%Y(-YlaKU-B?Ag3v{X*77G5oV?uE`4OojO zl+LYdZJ$u;V+mp#F$=nKE&k-}UYz<@#7|9EZM6{R2zUC9-tw40YPHoYs3`KZYD`^H z4Ec#CbcX^!2i9yA4O_#_^;A#Qwb7|a-Iu5LH;Tzc|L|IzUrfpEbi}>U%h|*d<^aKV zRJSDlYwGi8!nfV#)LG6Di&B?}mQFE|8PxwpE&E_Z;O$ictI-Xq2gb@`Goxq$Pw=id^U9i$>z8NyPvke6NF+*iXXABF(h8~B7IE`J1(PvW5V9k6I zZMHcJ5V2@!(6=Upxp-<-_=|`o!`IeXi}Sf~==Q()oAz{1AIRSw(+840H@TX>eUdBq z+c&w4*Z~MH!{uz~Lz>s#-nVIQw>I#@Z8Ri@u{NyMS^ZE=jUk$t%hCz-v&=m->~7pW$~+YQ7uVZIVyb4mGE_;EJ4l)OJH zT$Fr5hLV@O{#lg#X!GSCqU00OlzhU!g_2K5Q}PM_7D_%LP01(xTPXR2G$o(#Z=vK9 z(v*C{zf8#|q$&A?{{>2(EW{y9XlngpsqO2M*dBk#B-g3lb~41dVnuadmomR!*UTwz zR%f`@uWP=}AkqcAvxHSS$x6f_P&bZmCNvwSct+UKOBazs0M__;IGLh14aB>$xq&guFBw<%!!rhz`gl+|PZL&L-xx~(0 z&w*I(v4+?k!Lsoxu~W;a=j|lC;x%3N*)X)mi6&c5lA#9~`sL9V$ZDuF z#B`NzPJ&>iQZGJi&ZAdrlhC=Xv4Vrjif)cKq=*qqy(pgg%exOWo54PHHs08+tE?qG! zF^5wB62Lc&>;jQQ5fA$y%aPt;%6j0xuoqMh`x@6~fqc*3ys4mbPFwP^toEr2B>P7!zGsSzDAC81pvtlg}ENg)YT%+xFo)!h@ zyoi*FofRA5Ub>RQ())|;dyavg8!W@{R=1u8V%7cGP&4=@W#LJ&i)J_N{nhjnB72Sx z9~;?owTYL*tuc+869XxeeV&3tnTtYj)Jd$ynTO+08}hvagOTxXt#x)px{ssQOHcAe z-Z)NY*a_DW|%qJ`gth?J;0NSmOvCnQ?)POFi zuCuAS{F%EBOFYCEtL4AU_l@C`SBm0Jj3I^IFXNl(g?eBNp5_>bx@%L8?b`&4)nzzduZT70 z71(4Gan&nk&3Tp-uju1$(G59?Mbhv3P>F4@t5!kF7J!>#09me`Gw#%I9m&Om4HiRi z)-!hvNPdeu3U?-tZM;ql$q+QF4TYlg&)j)2F{GW6C+XNc4T5MO0im^?a!X-qN4-ltE}c&1+Q=>8@C=$F8*m!6P*Dn96K z7qwox_2_6Lt5Jd1piQS{l}nCb1~)N-ulLO0OD3lwh~bxv^tSL2+@`UQS47Ig`bGOU z7G{MX#q=Y!S)e0PD(t8eM(2!a;!neXxpkiy;-8%5w2cuCG#u5I=-0HOb#CYr<0@PC zsUf1tYsMHw(#W>Nz@`=5e3ijqzoyOSHmzuy8~W7EyWdDblND`=!<$y@@G=d|Wa?F9 zzgr~bx!cxZh+<@LMR9y|n7=|ysWSROXN?`Z+zSc%LHJ9=y(~F`I8F^4JI{e5`#fu0p zf@K?n1sjPSdSpHcCVc3oP{F3)h-JYM9|o(IrK5%}z3n+fH^dD+T=P*gy86iQpme-Y zqoXs%!97nwXQ_FC#MBbM&pVHxfhB|;8WKB_u;}U@x@t8)3Jzgy)ISjE-W@30QL!Qz zE9!m~G3#H`3Ls*I^@1Nhg*alYB`Y$M!r0XeZr(Wa$~vdbU$(-(v#mc1E!CFXl%fBT zHiA{`X&4-g1_$Q{4;wf*)UqL*&|-W-{b{NmoHKKg;ks5fevl}k&R*?dYBA~v|HD3b zuH5i7{Oubq<1d%W8ozOjS&ZIeHxo3rsrpOL{KaQ|e-eu_@jfZR^k-evqnf^C&)(O~ zbJ#z7-!^_5FJ&iq;Lgd3r+CTa{yi`0+&h%}_}TkDO6R`!&Z`sm^5SpW(oNw7;j%=N zd2OG@Yx(qZlHuCe9mn~bQUj;wH@&&PY2Wt7uk)pK*3~r72WT5EFpyf`mq}4l?XSbzyU4eYxf~$hdeaDAtn2w| zWL$4cR%0Yz`tm$Z0=aSy_%kn^d}))Qrp*Xy?5g*z<_FnAJp00mwFmI}s~Wc^n)Us$ zE7bl{pd9p0mpMEl2dZyHq9&n``7^cXZ|2L!rPgCdk@;1CMP_HDc+V-51cn<|9t6cw zv;Bqt1N#Uji`@x6_7`nI-%0}81*z8geSs`Id+g=bal z9NYAr{ytC8v`K-fzfN6B?Bmt8Dzdw8IOHYv?MciHkMfS8*Sf<7)$mIJfV{Y|N7fcr*ho?Y{TM+&6#Z7rl}sZa&>M_^4v7O zRcx$vR>Sn|4wkK`bDr}@-s~H2HU&lylp~pML+E@T+SZ>iCrp;JwTBek>RX1xTyLD= zWxN=0b`$Krm7(!JuD@Ipzd{1n>A$Axw)gs65F2$AftCZ%hK53{BniAPj>M&Z(5nz4 zrpP;=gq(eWwm0(vu}L-Hr=c6zna`Ux@w<;NyC+)>uYj5jFLL%z zzRtW#I{O+~uj~4-mQp+P_o{Ld?kLvdVUz2uscn;Mt(!XZ)Xmd--IM)R!%O}3x2qqi z$>pRXU#zuWdX|FU;>dmTI^J$xO{<@f?WVmve5{8L`E&Cd`jaHX)V2J1uS*qg(9?Q8 zG^{lhzbGKr_9G#=R;g=DL(c*58gg!2q0+CorFq(PsM4>P(lp($&OCic;XU-0l$RKb zjqg+MOXklGzyrsD#G3jyei4xh3`R+RUeZvpdK+HW17cH2SzdaFUx}i(+mR%()Ruo@ zwR~4PLF=WhESZ`%5p<$g67P)yV@c zTLJv4WdTNWTNRmZ*DH40d;N(f)6Xv0joXwzvX3wg`2BSft#xl;*V;hayL^7HU$Ed6 zd&Fwnx0@V&!o!sVUT$}Q(4K8^FGq))!^ZM>1a`@B(0>OEJLtcZH_(6mA$YJ1y-v&f z2;@l9M%|*z>m+1^K%lAv;Koj?muTBgscg~FdCPV*EU}O>QCt95RFju%eNPc17`LXK5WNCp|q^yGv7sPU{04o`5>&qc4vd9JkRf6ed z^|;a1xznF-JUNhR3srHWX=l)?ZA03)Li!=!>lk7rpFV(}iQVCI8>4b!dM1DAH=|au zmT~g{+i6mgCx~C6&2m{^ID3L+37O9hJWKOjwZV!=4^EK4(+x;hWPvnr#)`(16vMO% zY4H1i1g}|#N!~6noZA|cPh|0jf!Iu+3jp5v&n6!*XDb2I>cO=FWBaW97siI>2U1Ie zSRj_IlCdZ@Ft|)NVgk`ZsbfOdu7 z90E9go!EQ4FN_Tz5=bF6UJt)XzL4{32;ainfOml4y*cP~rQu~gx$qus;5Gdays+QE zTV&wqJ@hz6rN`ANW`6 z?2Ww9HxNnX3Z<=xc4ZKJXJR!EGGdCn@rmB`RcJQ~QF-kspKbkqchLGhc)s{Mqx$I0 zJoVKRr)D^m4^UW0xy>28VyC-5QTz;(LFn;*;|}&KyQ4#!tlhCxKkQ!ILzTSC1cR2( z1hSgTx{_0MT#alI9J0vHoG$<+x0*jeBnrU7|DA%ax{uz>Q(rydP6<5w1<%^>u|eOK z3M{Bw;ZNXu2li7b@3`|G`#;A947VCPwXXSX<=0)?&R6OK9kM@1)ALOz;(3K3=i3Ac zA6v|_mkFRqL3zOWHom?W*Jx&YNks8oD;j=;4$Zh@AmE==$2l!lG{Pj|#?+WSK)!&-nDFr|y-_x@g4MPka@@=D1>6 zK^WneWQnP+v~5Wv#8LJ&){vHbO;7BpVdm#iy`_pS!9&!JK5Ej45ZnA^vMWqvG*+x^ z(UwyEI4z^yHwB8I{<((BX#$loXh6!DJD4mr`i5DC22e!ZT-Wdmo7Ci4L0_C=3+P2ck)Nerzil+H!IF&pjHAtt>1WA#1IvfYgjC-t>6;}!dk68^YJWjT^2|VtVsxz4 zlb&@Xv2nk&1Ur+_mpzqQ`KxG8ytp?}dwFD0$RWHR&BVKV8_%s$m! zwm{Og6R8e4($4kMp0^gaaC=?q%Pm*&w*fVpZ*EKp*5XI<)Iw5<;79e*TKo%r$Xefo z(rY+|j9*Yj1pCO9+!n%bCzi1i%~tAnE$FQ|tKe_27X@)=rzDH9<~&J?USQalfT0}i z*5@RCOCmA``28{h%E<<3r8fxEsFLVfb2%K(dWFawzo3%9Q^geIAqSHO{t5{*^an&2 zhL42|Vcqje(0NKu9YNNGF)|6}jp!=tLM2W~up1i~er zAdbX)&`^`A6)GqxL^F`Uj7}6q5UVKlf)}bHB!X38U=qpkI4vq(T5C(|+tzw%;|&lI z5P@9&@Yd0w7}%sKn)>)LCtwf5R;tsSzT zna<;?ig4!u;m<9h0kx~Ci|j4@2-OKh71(@;nGZWsAEa46Y&IXTzcnRvbngbD4@y={PbfwKN zDwpZuuNv-}%1F?-w1lFUmvlOyx3`X^r=8>CPvl1hL!nO7hD)KdzpYSTKBAD(8ap3Q zqZNLN%Fd7W%nWgwZbQk(=BQ#NCy+^;>**+L0(l|3jB__E>jO=6JR>9RaKBw&M^D`Co#bXM~ptu$Rp|&Rh`~UM5Rv+04U`Y{JV>xo04TJk}VD z;(#Zbu_c!LF0+35SAJk{!bEl~LQ?}auYe_wt{QFJn{si{bjr&6-%~e?x|B8s9^t}2o z5zCGY$^Gb)he$iSWa;)-a?F`P8`gFpbvJ1yZ_}PlpM2X}`a>(s^2(`0YBe&X%RY+|j2kuzjZ8dRx zy=G?Z4b#rlqY`HblU!x*?D%2Iu}ab@4-KATNj+)AT+XoV2Sr$b`YDr$)|yFBDjSGq z@1+>ugwS$gik7@q2rVBbb4~?bgdwY@JmN_-`zQa{u;mH;cs*+s@;({>Radq++RD9UpW4HW&9>`Ik(#aG=;ipnn0^);6gA2un!jvghF z`y@Zs?xIMG9x-+Ra`|p+!4=rzuj&+v9+6)$`1tCwV99c8wj6m^@-RoE(`6!1?oR6G zkSD6}K%9}uK}Ua_@2Wpd+>*YZn3f}Ad&$P?Kf=56WcPA$D6`pGxT!u<=~Xa#J3FwY z18R3q$G&NA@vhrXP7F+wR{|xkS6zbqczY&`uTy0EOm#pn-ZkAC$kK1FUdB0GgLn`i zlBy?}YO4|HpHiSP@{O+Vb-@tsfgmYlBU6AhrQblHG6b^A|6#xZ$lkC;;m9_D@=Ijigu$ z*9W8i{UfY}$6h*dg#FvxJ6R&U9dRLV^KxhK#x9&j-K}2|5M|S}KjFW4^=+qG3-_VJ zy}_0G8b9k*KB?)N@?!Ms>$RvoFI!5Y;K!f_Ps)AW&4ELBP5-)i*)!#nyE@)T-xbt* z@b`>m*?Yt9ScetL!J^UWcwwXkcc%+Hkbt%a+>u^ZNngtRq&)cb}tl3cu6lRMqetZB*hAh996pCuMP^A0R9zFXLRC`~*ZHAXhPTvbA=dg)(dG21~)3-6|Vn+RyiQO42 zZa!$#PeS(0>8v z*wg$stTq_D-e0_?0|vha2Cp#~98?S*2hLueyGzh_6pt6@Vk6T$YoDNQxxIYall<{V z_FR2i@wZ{`sEJZg2Fc`uxl@l8ti3q*OM%BRbj+(|+Tz4}K#%O@Cc6id-DV_*g2_Wd z5cNb`;30k;`A%2A-QaKCTy6y#K$^t{I=RDN#shKI9s{1I1w8s?sR2(}1_!smXKk=C z4t&;0whDWNzj%ZHhPQQ|6TK&G06H6h&fCH0MIZ>vdzgK>@1x{Ozufn6&|Xg)0-Xwo z*3;$oT7P8k)wi8iZY^Bpm-{AfXpqWy>{T&oHS2q=wQ#q!aNw;I?JD2LBFjP3aq*gZ zY*~11exbaYr%4#CYb6}a35q=SD!Hb1sxVMd zH>HzjbN&yw3b^~tBZj2~7!0)ErYu1~4kCtW`~#|d06knI)bCsA;gyO_F~O!w6q`O$ zO1Rfh!gbT0Qc4Iet!a#>R%rR8#uO#I1YF9-lv~Ik;xow9N0BKz0sTwlo5ZW9ElIo& zl*k-1nLV2F@i)_y&`%Uh1wbja|4?J%9M6_*moBu z1rndIf?xcjxDOd+36Glt(aIet1-J4XBl(A}#3V*gM&rqDQUvt|sfm*8WU%OLs?hz8 z_#_f&!S!9*|A6=ctmg^rUJq=q*P+{ctL=NX7eD>Gwf6@?3msy7_k7>>ZvT$$4LEdr zKS^s(c=3OQXSV~}v-dP^?J=NvmU}vSr=`854r|!XK=gd}8NShoj^$4IbA$}q+QVPM zK7ZueK=jru((aLnL0+0g6%<$i*&mfzu=U%0ywf&Lv{cQ-<7 z^PsiPS$1pd7Aw$}WcU|7k2vH>_E(5xuOIx2+U23W*rcsad z_ePG#0At!S{Ap+RO^0OnuUiWdcZc3S(Z2HtPOXI9H${jN5LwSq%EGV1^6xwXNq$Xy zEeQ^Oi_JDxG-AKj_)(U ztcX}W5kzy6bA0dyCJw)XO>2G0`+Y{C9B984TL(%mVmFxwJ(dl{FCB|$)5>8g_ zR{4N-jTq|(!s@{5iH`Vz!pima;2|#iLc4L+draQU$llIVr$Uzv_Go3jq zlR5h7GoDjQ0tfT<)Zvl}WssRu#oA!cv`FqdNZ|(uU>_HHaC)ByP%bu!pn?){o3OG4 zvGX|?l*F+TY0x*H?xo`Wk23h;oOT~PEAsW%({2<0y-Pz*>E zOUl3G86?K`;_ZmBI;cLQN1%AcltS)6PP{i)e3z>8iSqAYb>z3se|1J4R;E>}6LMu< zwg`gZB)WTtVX>08+FX?9Z`v(f!o4ki8CNTFA#MAz1V{*tYKTk{w2~lH;mcWJ1F`$RG@VA zB|2A%DZ@vZQ;s;-xwmmJwI!awz7f(lm;DSo&H)Vw4IIQBCcT*H^_LUS zfsllqgH4Un2}~cWifF!Mp7>8m^L}gOW(=9IR@)=(zuTdG?6^P6oHCI1o3;HX#q^g$ zCJvYaEY`^d-uV)p3E2HH73NkW3B(3XOTKd&MOwb3QK%sChV;|(U4O96 znZfPx*bPi0Km)LhioXxnI`85B2&THyIXO|rAMPPKQSTwL>#&j~E>l?G4578N3WKaC z3RW))*hrB!fn3__aed)a2sGw`-2ri9u{&FN6)jwzgXZ~ah9aR`xDee71VdP3y}zPY zFfxM>FWqr=$|KG-4MSjJfBQ$9?oc%17_oDXL~U`8^dcD9+hb~3kd2GI$Iq$LM8B=+ z=h^etY^JlpNqZ-UGB>?+82!a+U->SZopTNTdkXMBd@+VgzCmxI9IyK z&c4UganW<7e|6e#`-K+iUtrQc`qz}+Kf9)-Op1u{S6BgV&+Siw*Hho&(#8HVo@nVG zaH8S7H|p~x`%U6kf61czoxi2~uNN4aaLH>PSla{b7%4?8$Hgh|NBFGdF@{>x<#&Ru zZ{PtxvE2TnCOGr{ZN~80;$?*aLDPem+woF5WW`pkI*#$Crfs%LGLB z_p~DOc~K8~?DRs#dvFS~Y9A*p7_F5$sc%m(x=5?H$JC!2J>oxnq(sFc_+>xvYEmnJ z`!qP|jmdJR?)pw45$HaqJ&STcAAK>sRZy@#Xm=4z4B8{08$>X%ae={&oZoydGxS(_ z+HpK^{bVP=mX2#^yk7yg#BqT5(nX3b3*~E(d=;lE-&|OdhcS1p&XBXy$XyNm5{j?7 zn>bDS#-3mR|88>%@S^3LZWg5L8&3v7xh9=?8FKq_1B`OCr!J_(Bz&93#B7OiO7cq< zd08p|m?btnWIr!*NuVh*S1RG3S#Z-mw*iSFF0ssCJ>D#^%Crvo)g*P+#}ey9H zw+UZC;mT-rCf1~%1!k?1IjSt#ejC0EM3jF;&iNFbQT@@G#LW_ICK&yd znbn~?i3}DhPOzWmkg&3W11`}p$;1M{51B)mq4VsT&vfe3s>95pMX+bmm&|)xa8esT zZeY@e$*!-SVj$m8O?R}x(#0pz`9&~~%{K01ZU!TXU%Q(|!y`5Tm zU|0>O)5s}pf#_puc4BXFeaC_d+((pyTYD!7dZ@>)Aefb>N0`{ej>w7U!PY?X`5_wu z8Ld@|87D9y zUJ=8ckn^G#?&!EG?QJX}kX3-7BUC$~kn_y-luH{)ZK>2_fJOE+z%)tM2uBCg+ZwRP z#X>gVvnTHf+2h7R$|rzB^_XE?AF>5-74r$CgB}x3ZPol1=%|4;mp+ZlaeXsn_M#8! zP*O{6K=VXHokR9~VZNAQ1-Vi{X|UhEw@@I;6bJ1qV0o_yTmtr$IRTq(KK5#u01=eN z_1!3I++o6%vw<&dgE4?iIGLJRC`P*fEsf>)kK({#I&l!4`qM$)U#0_ z$5>)k|3RZ%E<(|lMzg4F&l z)un-^5qY!*Sk-=#`%2*55@KVhw3GHlir^nHNiUquXIu*Qk_E`p zl}d8IC`c6$1Dp{o;fZ;4TlQ{g-ChdpE1iLbrk@1*s;86;ZLutJ$Rm7FN$~UXZWUG3 zTfLMO33Z&cQXrT}_DqBe$~|Q`*%%JkzlLG{QK}|ZBLNJ8C2v@@a^^!f0<)R~RYT6TEy3u(mC$1m z9vZiGc6~?DA|-Oxr*LOG%vUmB-@`K@TX1Q_^mOLTn zWMVLg^zz$6fn;=erd{!d$G1NA_!ePsg>M}O(gtYH6T^fCCaw%dxiwuyk)b=d(x|fd zGcj*P68W00Gq}ptuJ26x&jJ^Q_3r5nHl9$LJ`|rCU+=$ zN2g%4qEo13kHn3>w@@YvVFgtoz^wtzR;~C5Do4cK z_$xL;6C*Dvp_zID2b3nDVaVQ#eHRya1v~;07qd2zAOKtgD`T~x9A9ToB}DCrJfTBO zLLQTVeYi|@RIGg}>(rLHs(>}nrFvo-jWId@Moz4#6W1Q}Wu9P3^cl$pF{qf%=H>}5 zStlH>QmM3FUPLdG#KmdE$g~omE<(o%F`7@G9#O{9O==9-9OsOL7~KM0mq3m> z?hF|>tc$jj6}vtM%5JF4YQ~yQWum1&{+lk0`VUzcgZS$DDvp(fap+A^FQ3%3CHCuO zW&v>4atpn%t~Tu6`GDM6!UXNrkFuJQz?{-Td*^-$GJ)@pA2 zF4a8aRg<=j#Z{{6W|TZrZcr>l*_L%qpkxQ<7CSJRnzbhroFX7fFoG9Vw7e|SzeGA8 zvMRO)OTNHuYI{(PeWmX#>P)oM?C}Gwn*)6bzw&`Km+jYXd~c|-%zAiLS{A`bKpT7TaYa7H5zjH&0)3LIY(B5p~L9XdAFs}cV(1cn~!U0!P$v!6&} zRox}p3wFkv6Mq(Yf$KIwrjxK(PCV3+y-S2g<{`3b0ykk!sEpp?hKAgdH}zx*l@J+% z#r8iKi0)Ad3M`MhPu+evN;19w0t>KdY^{qjs;nS)bGg2k!7#9-dTGcxN$zsiHR%jz zeO9zo4*3yb0iuJ>`VU$^5j&0)o+lSqLI#49{y7@fWwxyKV@ zWv^Xn&&b1DfPG;odhLAW(*STE_dkPk1b{50-$Pg>ETu5?V7_9^K72d?^dVw1*!Yot zV767Vy^?Je`*GQMwe_NZEQ!09csv2i=*Y)qIMH!d850kJ6Gd-hPn$5&zU2D43vPVL zFevFH(^=;2tzjHZkSQTWzRpjn&M)+VXfLZ{>Urn--lU;#QVQJ8H(^Yf$xgKIsxjlx z>s+{G`}9zhka4&yl!TnC^Fu?f&QVC8Ml-rY%#zi>G=%K;2yveU?drlUXt;u{6s<{I zxIQ;LVd#`?)!wT;%^rqa&f*`%o9p{P$|qfpL(!}Aj5&>%8g6H>YW4%TK~JSz0s8`( z=o#;e@L4B>h1oQXmJ!arqD7=K=`IQxxmWZ-#I!(@M2wT1Y@J7P$ui;8AgzhsQ~PtB zo!8~^A(;AtRbr`;GH^Ha$n^B5ENS3;3{5YE5Yc|UN>*IM#jcrH$XLN6CrX3N?9+?e zTwO36Pv>);Y+m9pJ*bZC>oQeP5xm{A!Xs~cws}=1C6G;2l79MD?ww~7H9>+a4`Mi+ z*U4VDcn9>tns!n!vqi42OBE^`{1c){aNSDDn(EI9#UOSSH#a36$#F_1GB}>U-6vXA z7zJ!i2%B%tjv0#DG>EH1WH!Eu3FCPAf=jALrPsaMG<3FWIB{l^BM&Tv}D)v3qWTX;vZ{CUCyJWf#9Y`Tr$d z*ZbrX*H_PK@4qYV&H%V0mG)14E8K+-vICU6{=VRtnA1hY#@?A<{B-& z0(4c^52{*DRfngl%JZt?i$JuCd_h}W0J`A1h@m$?N@htrT}_)`n-II%mh2m%gI0@N zfexr-jTMpG3w6RqTsrsa-?% z$RZZ4(g)rz!Ce>gyO4890SAZOgPH5lncykPD&Z27ZJm$@?hkanBrj+$54OH#&ht4S z;QX$+>PHgOB(glKGJ5Qfad?$T4>*rkZ-E6C4OlPBd>S3;>Xg^-m)DSefxHfLvce#H zJ9@R-dnc7`F`=l0=y&GqFXHTcL1!XCSaZS{dWaWe^jG2&AbSqGp~87#PF^wTv)T$k zVr$N5GKFr~I-et}3!k7#4~kxdpqqs&j4`RUJ3lWMW( zNycJn5C2VZbUZE(pCorfsPna}7l#q5;Nt^!yBj3JP6ZlU8PQb z8{|8R1!F$@wlMc$iDPgnVTP{DT;b1LS&{icxqV_lf?e^kpOm2p%;v6e>kr4WbBp zps|c#YOAf;pn2tybhZQgPhE51kNZ^Aw!^=&;X*?wGQbeeCjb=U#=I9CX;`(Qe%RFaL)3{2Sta z{6(nRZ)rG=SzIk*SsX)Qk`vD&0D`<$bo-Zt>X`NZ8T=!?6Y26eGTQUk=EE5N`PWg` zd-6p3rQ!EZpz@*Jr-&ZVV75Agm79Z z%>ZYnd=@{NVx|?TX1KL5G(H1XP~BtVaQou%8TPu!@-{lv%^%*^gPR<{oJhl$iNlll zwJzRTP6H@vl6C%B`vj)bCQ;?RV+5X3>+94yPv5lS#4?%fwEp?cLW8NCEiqTl zb65LqU3wDwVD>|pn6U;Eo%w^nKWk+S{7I8zNPez+;y=$Fn|M#eAnybYEO@SG;`Ou? zGBu>^?b73M<2k)1SiBzcBD;>_7H;EN&S4gAy#$p-HYNhkYzeogZzrI1|j zyTgh+0Ql7J>KF20Z@?w9Yh9KaH>EP2&$kd>|3Un_A_I8QT;&$~oaJeCbv4;=rX!mK zeDJb$>X@y8FVu#I9N8XEWg}8VV-{J1?rT=%eR{|2E9QHV}r;n*Eu4FZtY>vsWG<1E;bVb5|mJ=`u>Su84rz|95J`m>wpQ0=F3rFj)J_L*d0?}c7+4I%3 zflS=A3a%}gGTJHcv)`7sn0N{W-8I!4c-SA$5n3NDeSDK_CHnPb*wNfi|0PpvlmTm8 z--XTPrRW}q8PmXDKJR+#sp$u2!_-aklI`M7x>sNZSg z0e#PYC#}k`$x@uGVzPN3z`OcAPB2AE^t{T$AGwUGzsO51p<=>qJg_2E(ty6kU$dfmNU&t}v@_3*W`W{6 zrk)lmSwD49sCeU)o4BXcnk`3N0UVoWf51bChdE+K7tGuj$lRAWGbEw#s5pMlKJbx3 zlZbKxAF^iu(JMD+xt61*ZIY6?kD_1!yCFnGE$jCCx8hj#2!%F!89e(uwA`9P%NS^R zr{su=4&pbR6_b1a*CLtiMXu8#zELFTgq_|=(R2^9p&h~>?rB{gxfNO~eI#@j3+W+~ z`ns7m)wPkjBU6hXrFo5q-M>xJQmqlh{wMG4^PA#FvpyCE#{pVc4}9NrD)Wg(k{5Xo z)s_TZiNuJ4GHf|cb4T%BIlq!E)SSbQ1A5&E9(peF(rVOZR;_z1NvNsps2uYJlK!fC z{!i_7=S9l}(d1lY!Gib?$?V*{wFvF?FJtoep`OUKe6F|A#5i|nnYShOn3Z&BcVnkT zNL|MMiHj=iF;7ba1BresZ^} z46Y{b4fGgl7WtU*$-kz^7d#0rHAOP$wLB33<6#Lw`;=3$(iy|ZtLxdM4C+9S32?#P zbsrw1?cIf0&8y(~h7SYX;BVFSk>xq|m_=OKyV(me!!BsUhpn6XwgxtQDjABG^F8yf zCH@6R#{CSXLrbS%k8J9{{r^~hgMWb)e~+m*^`qRBk)-M`F!fg_`@cQd4TWHO|BIJL zww{CLRR*9vr{7*o2}BhjS$jR*_Z}znD8?Dim?fe%K^kf6Y}Jf8LGo#=9R&l?zJh(* zLY-guQZ_#2TyhlImltr%{-<_7+lydyri%xo9LidAPNO))YH<7mzHq`~H-_Kq8rX1C zJ;D31TJSa#{sr0bJ#bU1Tg2g8y$F3oNPZ+#98-oHxd3GHN8H1>$BlYO>qLCqN36)* zhfBPWt^HJ%UN&?%cQs-pO_K|oN=1OTX8%9xG1<*u;&Oc|&+!NN6LS6}INNS-$0&xp zoDTv`9ptcB#Q5=YGlxfm@9f4ZG6Ea6f+m3;74?zkoWw9er_=_t(%#e*k@CF-s!@qv zyCrtrPS+(Ydd;7Xq6&LsrM-_h)ek0yi9ZkaGia}I80{TF1jQV0wG4!H9|s$B`vs z%LUfmRt0WotIZphLj<-0dsp$kbsuH!6NB$fM2{=pm$}Q1>>zJsYeBabdrf4U71@>3 zZ8@7UwmOl<96a`&G5NcfXH_4LJ%SRV4Id%TSo4<8=Zb=aFy)LORWJlS*01YV9ag}s-} zi?y(oz{pG^>b+GZt7U6gvo_?6=VFz~+$0WMn@35?@P`UVGo*(EhXf6UR4MuMFX$A1mG5T!Iab7NAOB0q%pGtxzKsli zR3R_Rh&d~mb-nXPPK!}dVy#z0?Atg7q%3-X)5MVg4<;YcH6}Y6fVtuph~VA_po~E z=5;<+_!c)abFi$H*4*k<+K1n?3U4|byM`U|1IHGkYAp||_a+IyUm;|F+kB_0Pj z?w_eNCa1QUO9NNgl`Bbm^?u`{47u@#*B%zXn*7x5U*Ics1!?A7M1tsXkRq*`v*@RF z_X)ZxD#L872wJz?zo2LQRB{pRu4K%7=!hIZM9agS{7V_7k_hgbB!hmg&EzS*`beb) zrq&mDvF>gLrXV~~)Z1&0+_flUksP7;)!nMxD&OH&Hpox>Wt{FH>LRivx=)-d!HTZH zw->tZJRs^lCvpUTGh0fUrd};VL1Z69X*X3Vr%^5gQTkL9s_X3?%23L!Wi`XgSi==! z#=lECZ#Oi?x}iNBmzco6Kj}V*4C{%i_KOh69wo}R%iCB=%@339)x3&bV$8lk95zlF(hg(L+MkvruGC;H6r=Z(_)bh{z z?q)T=2FE5GQU$FBH*BqpR%V9aP&BGhw;OYW5$@}98&?Va(_RyQobmw9Z}0HW+A4g) zRBz^F`f(UgwxF>R7BQs~r>bt{C5=S;lV?TVAbpmrSP~iS z12fDrKyDbClpEq)p^JWEQ@L|3C;0nOg@4I1Voy>JgAOi|^FsL_vQ?RFghJGe8N-}; ze-bH=`_~U8Kd(m=13E_j6uKYmhRFuByCDZ&QPMJHbEUmbra8_or@pv_M2}05w{@ex zuUy!;fxGL5;f_7AJagSJ``*U|{rxz&WJ1TJuVA@|YE}&~zcK>qXd_)?H*^ije)}~# z`Iy(q{z-TlRQoag1J%YT(-fs@Ww&+Gll16amk4*ws_N-qaD0$m)9%#scm`v*`N74<8pjOaTkzbXd-bh6vfrBzj z%AK1U3L)KgQ9CqT$vA1dC459~pTjWVzz{($NaM;ZuJ_#- ztAH$3+Pf+<_rWA8ioY(mZ)&K1-jjAjppSo!%&hz-U!{T%1j@WTXWnzfhR=}dlB`HQsXzTHR zz+Lo=XWDT#jDFeE!{tQ6ZIo)>PTPM8A_X_dby4;H;@72Bf9tC%0M%Xv*+_Q5T9!2& zvU+qo|CVuEv$sM}lw2o98v70djkNmh-orWc8ic|(;e#kH{eUHkB)r_ zVHR=s8m35OnGtoT_6kOSk@;8Cy;lH0Ku)U`d*4y!^@80jXZfNjJB33$T?seBzT^9t zeL?>Czv%HH_mJPVr|C=t>vo-rNF$31n9TwurV*hjR#Eojx01)vD6CemaF}maud>Pf zpTPf7{4e8wfBqNnKhNqVWoDW(87zMizbRv2QCIID!Cplv6tMkyl)jMCRsScDv}wWNI0bDNOZ&{=Fy zAx<^d!b%1Z^(-RWCTrmX$MZ9Bz;fA3EI46eWS?u*_NHI#P9{qBt~}Q^A0W`jcP5fO ze+>aX*>lljto3MYKtuz3mlE$4?YSRI&%G_D+ZvD12ZUXt&ywxigYCI*Nza{Lw+zPK zMfYm2Z_hl;WY*0$G_>1tyTw+;BLHW9GUBCVWtJ)+G#&vIdC?<+c|wljGj*Phjvp>r z7n~ID&ad!C;hu(d#x@aH5WXnLEb@B*TS)kNfe3juZ%cv(HbDj!C9B96MoX!lQM$*ED31-oLUe?gD0ict6S9NE)Dlqge9SL4Fytu6ult;csoHX%nE zLH;Myfkx(z`N)&C?(H|ZjU}t6ZZud>3z{=6cPUDK7{qlc&~2Zw)5Mg+2=IHlOdDu# zn)RWl*|{UB*||!{J-Rt|3`RQ_C86=NZY6uI*|T}%CNX<;N+tAyQ3>syo@?)fMaSSwQ{;Cq~+i zvwrmp(j(j17H6M3S+>PlxNZYJ-giZGOFS7OvWV>hL;%Ua2uT$b0=v0sfDN*O_Y6|t zj6J6G*F6(55$aN594Xko3;YDO!a9KM4Q_*7TU=<3&;vYdkF~UhwZ>&_l2ikuhViW(zh;!7gn|DAN*>jvVNBlg{kDbPt zIBh!?_l?|tp+AF|_4G>zM=`GBrye}6I?8>+xW0KvSkDmBty%YW+#Aj2T{d@-XLyL? z+~BFXpA#habixCg>msTQoPjzG&N$^PzY?Gdr9kLCQl!zE!;GX+cgwyTU98`2KzB0r zb#78*U-t)7b+xDW*pALMJ_i*WgX}!z3{|N_rx?=qMH*@A>{V?m)ql4DlPr+eFB@0%=tRdBrJ|YsF6Z= zGveYxhxWU^_kiZ0&6Nvd>V%u6?;?LsHvfYC^@k;3p!@54B(mivPj7{|sl}Xrnlgz0 zwU0@qPw{6!bA7kOvGq9jp^kT|pN10?FPlTr#_Hn48GOaRU_6&Mpr0R8=U?C^ep25p znb*t6PTX3san?RLTCK*zfvDMS+!-$2tDawVW@4my9#eP9n3nR)k8o`C+pYe_&pP`{ zHgRgQZK)>_)X%+SNQjZ@DSds=J2=-Os;e%@$H1 z8USg1j)eKIwBPiA?C4=DoeNjm?}RenHF~2!R2|M--;cJV+Ei7Ntr->InN`=*1lpW& z;6$bUkxX%={eE>{wgb~i8Zt}v<)VqM$k^=RPo3gVc~6<~Kj>4Z`oj~a)OSI#Hs8YstQh$c|C~Sded4dnPj-B@mpNAuczrys zulwse$1n4qdc`l~iR}d&@anF7n8GW!#VmkbDgwq|@^TUcN;V1}P7AtNwQ@I9{B8a) zjQHjJLVh1zfDym!d6Gu_hoeY2RQkTHlJ1lI8f_n=iD~Mz;j5D>M9ru+KkGGLuA}+d zEh#SFlATfC*Khwb9tB+WC&uLptNP>PGx?#`uhFsSSy-Fv>uYNLNRv=v&oT|)NQEJ; z;gJw_Z8$Sf>Jm-D?&u1WWs|-m2GF;+O_r4;rTTWJ$=6l$eFjkKT;EkDZPIhu8Oxxc z7**w&lwML))L!V(W7^)8r0pvQBHYz{zb}MY@p%J zovMyv-&I9On~^y?0&WieJCUXwx8FoSn`Rx&c|^+5YcNGa#8C^)=?{8{VIgrxsEeKS zn{49yBfyQEJw2qubGbiLWv<65M$1#iwC2%f$&~lP#=s8`KST#kmAe=>*s^ zq-$2qGx9_@AC_vUFmDx?Sw*&HHg3&U*S9$rXXdaWa8Pca(-t|mv(oHGFIizqUbK20+5NZ!fr;NU_$-IQ@prxI1Fp6WbBAp6yu}uwS)m zt5{DV`x<~mAC0G_wvFrcT@oe1KsqCf|X!HIj*mPuEs~}IwaJJCOsobVo2)x zPGkk1A00Z7%bM|&JMD20jrpI5DPfE+6DI~@^I4MtXRvM-@3s{xBX@8(9xC}PXqCTN z)f;%43sPowkC#v>Yq{dD;eov1w)O1VX*7FRd7HI|1~~d^i&K2U(HGMHub4j&yI5I+3Jj{C4x|+ zXetfIor(;JD786!Ctv)Fdp|C#LmxeZSIbHbY9)aT5PfXs+uU%!DTC zZPI&n^eA_1f%x`gs~ydL7&?zQy=*YkLVi$AfL0NBsl8QO_9<8LSpu}E^=}ytin$+6 zr56OVBHl+4u|L4GrW7dMeh&dW&(~RNZlh*#)5Hj}mGhj~`OKaScj9cB#(Ipi)xH&H zO}Vtk_5F&>Sb|U3>6GShw z>SV$50{rF5g(ijy2U~fe!ZNG4XQ6X(;V4!|9={hSE(93&APERCgoqNq=-;OLnT+;+ z9j!$6$~ldXYE76`n54Jdsd+PA1ylFr=prHiXMdxt^y+hKrnC!<8*CM26Dd~T45IpV?B=`n+jKu`?d&A=w zAW;e)$H+3IdV$C6DKh)t9Ufbr`M<&A_kx&*fX81_>;GW<_=T9=egiy4Z2TYKaU+yJ z1&1l*A9Ag)EhjGczaPWRHJ?5)Oy|HiwHNA%^HmgQd|0;mt+CXWEmUp>gb@vQ_^ROuLrIak3Bg<*6tTTQuu|^ z-azD>jH+AI{hwBAT`ste4tkD)uJ5-p8~DJJ@CQwBOhUe78%nA}sy6TTn=CCzUgxs> zfYVu^Oq5O{Pnwu-hw<#?d}xDLNa8J;uVs?ccNZU|li75VPYLc!S>-inU$J%X&Nf zmhXpOw>&9x^}o}f(`9Ifz^}6eA5I7#8XnyR#lB&^ZCw99z+<0KyLNi~s7#nge>&a# z{orxsU;l6LH~~g^EfB1~ zfc>9DB_FSuL>*653Jh?7_6EsmHWZc z`&$s(b~7hlEvsTX{37*Al}?pc74eSNF$U)tUBWYEJQ6HT*7J!1SX*PrN)h-F67`>$ zOoPCLm7+h%uCP*;p}<@$c6iz+;o=!+6%*5x(F)cv9Qni3IJoKtQ6KO;f#=r0NK@s7 z*NXr-S$8B&HH9Li%RebLPCic$kQye1AtGxF5N;bB;6lsmiKF^vc7{MgcP&jUP#uH# zQ`oWg=sDiqMx~!~mnb{7M_|WGhf=M@;SWq6TFEyD-fqlbDj3)}w9tceMib&ybeOpn@MsI2To>}!x| zv^POG31Jy@#v8nQl5PgM-avqLg<0HIjqDGIwMHa9OjXQhRl@n~@PypTR2WGJ>J(CyWRm#i({(ox( z6ucVVg0;w+`bt|LAye{asfH;jBW~APoszQ5D&18FbV^3aluVE*x!x)c6&A2wr!y!0 z`MonSmOc&@TG>7){|1Y+iHEe_+_8s{7?^dIMStn=!6M}wLeis4bg=}8D#bppY&yg3`>xZF0pbH=|t0tzb4EAI~su@!7G!#s2Sto0^g-N(8|X&6 zyRgVNuL{CJ>dIn|&u7E=cZihPuNXo5d`c$r(o=?#qM}g9Ic=2I`=Q@`llJ%8a=^*m&5z^DfP`RzYSo^Mh7Tbw zMrz2xqmEqyn#*Euou9$JikQ?nfgz!TIhlk}kQJ^|4cj0nw@h_^tN7l+Fr8zX%RnN*H6F_omorh9(Yw@)?>B48 zs!3?=xz&eY(T1o)+oc})cQBfN;&BL&j-Ase**Q(HicCS-JzejZ(!wRczdM1-(E?!y zCJDJ13t?p()0J2h(i4;&0Th#`@+cafQDSvjbG*C>%A8Dgr2%M@R{#q8Rc3dJNz{4e zQ0vXwPpq0+Ix9-PPgi?*y&H%s*awXU(mEr=fV~n*ffmH%57~FHLlWI=h8ju-R4Kw+ zSa=*vGTXjZRs~=ec1SD~>6P&QC(ptlFtlheVbAYpolq^l8h2|j_k~rPu#S7S~n(;I$x~M&y$r z{XK_wi=#udSKKr#5q?3T-tA*(7PCmaync48Y&M=^ic$n3?Y;n}dqXmYW%idU#pUki z2l~LEls^1QF=J3nJ_^yXJozFZVM`5V2(dnuG7RUz^^M`LP=<|+4D3b14B6Z8v3GsX zGc2v-M%Vzsf#XN(M5|iG0z}_yTO*v|40@TupEp=$ia*%~e=5JHfbtL6Ly{|;pT-qH zYQKHHas`R*nwTJK>iQfV-Zh1jJ1#zvOYaW*h9RpWum-Sm&iQcNv|_~=y0Rs-vw#4rI>f$PhmS|g*5 z7hn}BHTf19H7>%6-cUfrTuDG+MqzAFzVKHsL7yW~;If4g++k(;D&n+%n!vo>tY?*ngUKBf-eC^N|j_*ePDpd;tZut8}`tfWPdCmkBAVAe1 z-I1xtGZg?RVY`tB*LNp>g|ICLfFYYubRGxZDF6j^FQoxti9x&9iJ=YLK&Qka-4ghJZcr1j?Bt*o5Z(lo>{c4$xm8PXVFQbn8vUrF0! zkyklisIb63PuU)5%3UN>FxU_=WYvyD404ja@JvI*`X^-uhW8tW*8z*K7d5i*MIsEM zRSEt6WD+y;Ie-x~g= z&);+U(ahg%W&x+q-}B(3&fk+f5J#84|7HH{hW};$o~9eA`KwGWG;jV^Vg7ia81t?3 zSN_=lKjyD>;KB3v7Q_3_^EXD8f7<+AJNMA@cNgRR=J`88YH@N4_;GwcoV7;tAw$h*R=qdBrtba~ zbXJpl-Efd^TYE1FB~F{W zzy8w9UEKj|uaN;O|47s4N0-QqAzQ!`e#Unr!@0hH8@!f7u@3rt-ydai{@$3R$HecM zM-5WE6Zl5)*jp1t3@u~`s?S&Y3|VM{1fNV|vbE14FA|WH|L5l^skDl-FhyWHwMaUp z?ZPdJgz5;ILYwF&1MU%A#z*-VCI~5F+@RMUkddCIJ?@Mf8OALz3=8GIIrw$^{p{uR zLjy-Mag9-fggCu}O_!hV(#vK{xl;X;qYX05#5$&c3>~avIIlJ8-$R{${6stSTL$YL zKoo0&V-niWKYEjzJpbU+cRc@CoIVu25vNRLx4ZZtW5{LnP|C3B88MmnO#SFWf(y!m%G)!dnEUg4JOAw z%DkJ$OszEy)lUnJMUrldwQO}=5+0R~NTpnNmmmKfJ)qo!QV#ux*BfzjpUjCnwm4R1 z2!kZfpnqOiAY=(?0l9!>&aFv#7ZA8V?~($m7}-GTzvF_g)A(oHV<^@Z}x)av>}Iv=~z=nu()yqy4`r9ZnEnjiK3`B&{)fFV?tlxbsKv~X+ecRv$siGj!+*UPMr zw+h(N56axcMxM+IDyh5-tENdl0F45H8H!br0D&%gWlll3g$4SS9`cvWfr zMGA3_0v%M97dcjtg9`?5@bM~~pz|iGV7%>^A2r%w+F)8`WI?u|DcQ-;P?^ATQXq=b zNKP2A=+JFko*X|VPmhq9rFZJG$AxEX2BtITs8>cAdxu0PRVx~8%vS34Kp8C^MK=Wx z@?xJlY)o+V;-4Z4vewmhJhpu3BeREz^ zF(NOsDqv91q2K7hTWH+^xOoAhV2=V@=M^?c5?V}AC|Siu$0W5(4n$uloKIrxeqfO} zM~=!^c}Bq=(*qf&rtlFmh_+oz=b64HYmwQSEFZ&?N#<9^I?DCgFUSzQ_sOy4vW+qJ zOL?&|CrV?k?-hoX+$Uy2WDNFlGFo+`me+S%v3Nc_5qgml6WeK zuJ1OgG4v^Y|6gEk43s|P#3FbRGeJYxBHsEV-5JWh@MhgEN<_iz2ZX43o5M3<8^Q@k z%jWQCK}7AS=GZ6sqYXQw|ky~!xt3GbPClH}i zFI6J64hH2NW8N(&^K*_yp?kOG1)Z@XMpWmMo4bg1o-XTYb3M{F%fup=&)tb^+F2tov~k8}yHRWay|Y zHax4;62*Ge03}(So|E}?WA|Jxq6cPS+}7twRv(hLtmcy{p>44>yNwOlRpf&%gY2md z%0wgYdS|B22%-5_?FE21ayA0tQ?jJY+4_8aT*YW+K>s(=HmG6M3@2IlDB0)9h#VL) zuqtV->ZQbgEXW21RZFTS97itgeHQ)jCa*}ue4wJUs?#g#c{r?43W#_f@K z2D?aB3_9&wps+$v3#`2E$}OFX^4NNhVlIXzuEqTGNG4d@{gXa0Pg*t8kqtRd?REYP z^67Zi(?ZDZ&lOv0ga_#~hd6c8ur|uoZ=Xca=*#3cCs%pvt*7{gMGivyYUP0mL{V-I+{A z{6EwJ3LjOeD11d-J0Ja=p`~jW-qt1P(Yc)1smDPmd%M1QGNXq0<-`^q3!EW-r%SX{ z-|c)#mlwg7!DeZCLPEd~wp3qdtU4!f?FH7vAmecEb0DLzw7lUtRvxD&d7Pdg(7-WJ z{j~3A=E|ZK(NQtuH-8sI$I56(M)fNLcFW>}sti_P^LWV_Ej=ToqntjceU!O6Dz6y3 zvd9V+(3aR*jxS^lOuSSEQV+Ve!Z zH(>p4e<1J3&ROzP0UWwE%LiS9mp= zPhC=<9_14^6-7($VK!Xfy|SEHKgsdI3+|J`py3Lx>@Z&#>767BCS73G zrFma(fwSlT;n{PDn1xImicV9BX)dpvrE%XTSwqg#db}%llyDH8eK9?gwT29lJ(%Z2 zDB!$c6%;!S`4`5<8SMRfwoKxcG9$8a-b(S5qT&&%L|4xtsLV)eGs)!l zn=9p($=u16xrqyf1eqEpNDY@6RmWJZp*8mI#pYBA0hD22V2Q}`6TT%nYq0YFTuzwvbL;Qltmi?(G z7(%+wWzaPIJTv$0vLUjX2Fu?PxE2+7lG^ z^oyCYtiA2?T}C=MNWb`ERPgNrYEMb@e+4vx3$rc~K)uE&Qv%+B`piK9HQC;MvfjM* za=)Ry3TnYp<8KcUi~w4ubDf^z}ga{z~WUzroi}NEP5aMKT`<-+#*5 zkCt|sCE%$0a|*tr%XY8IBminOd$CYjC&SorR{vl?!-wL%YouwZlG$S|oagM5AV;@~0XgLr> zH{%;c)}{XseQe}|GDgGP8Q-ZgzME5n>(gOyBPr;U!R?_#i4xbBp^N8bg#>%;{@foj zxj#m$wn=ibHwg_Bxb&pxTfD?xp{RmDuIr24!p@T~^$ZpJ+=EB-cm43}Uk?~jzK-ZB z05WmzDCZncXz9*`QQ7;C)68}pZ<6!oHcv+0(lL&MxRm}>E4^GQWxmnB8>e|N4JtEI zX{tET%LBi%GfY>4r|Tae<6n8+mOHFxEvt4Ld2uC_eMZo!@KE2X{TInxShL`~tQu~y z+`?NxeZ$c9%#_>M)L3hVltnL(Jd2&waIYW3y?zYWet@*OT5;`atF}9M!J^U&dukR^ zI@tI@=K*hH*(LlkN$hHw1sT1(BrP;4*JXe<7Kzw_8SD$I@G>G z`>eHB-Ps|tQ6A1?CB-EWiR;@5Cj2lIxPFxLZo&?=F(}yM5fFA@=itSEAC>B z>}^X=p?23-KpmJBtli9>T`$wxc$bFm-~K zzR_Ot>AYz2543|^>E~7*3m~AUf0Rybi8Y4IdO)@Ckmr8)HC#S<3tAc z2XO5dk9=T zYAUFVJWulC`c7r~;%7+xKAUN_Uo8uN39e<&R-=!6Ta%FWtS7Pd(qj-1M zFBI<<@FT=D$HTlo3pHf(FsOoZ2l1j*U)_HDnS0lF7)=Yf`qA2|?A{d0j2|T}+bhbf z1z*zJ{j9l|i$+a0^G%9T3{(`8=k8U3Dt6Vmf=f^HDaCQn{}}raFe%pFdePctrS~M@-79Tl~)5VW6wpnGp~KHviMrYj7YuStec$@5QQ8 zq8dwwidQrvt3cyxmxmQ}3tdI7uf z5W8IRL&*3bzj^%dX}CzbpWQB_9A2ObsNqFT!&Uv1xQ$Pr2<>XOul{ASdO7{1`inU? z`A+5w)bz*chqk|j*?KCXf)19KX$RTC=xx&#R)RAY7n8@noXjw2^V8>9a2uZ(bNy_Me%Vqo?85UF1fzpEv{(@LLuZi<)Vb+rUFZPS@*JZ>BZX zhyI6t${p#$R%I2POuWHLZgLJfXI47+au9Z+IL02>nw?Et!6PgA$t5#$HQ|UX^(&MpI8t+BoT;QH;uTeh@@!Dgi z3JUZ(-2Zs}vT7u*a{LzlC=c`Ns+VfD+1RsUlfY2oHI-+8Uk91*pu+ z@q*?39ueG6v+pST^}*{|@mWn0X0?Txov8ywAPo&Uqq+|?wF~t?FzheYO0nQKFyv3s zGUp7d8`z)AqcMcai?5^?&!^-p)}@USdJ}c>pH19q3c&;g0kv*`JVevIMgsui+%W6*3Gb z@gu^dILVJF?P*X>qJNU%bjTjJaoXG$xB|N?NmZpU5^X!5`Td=;h)VdDfTottze8Ss z$g8p)OM2h?iiwaA`oxMFoYN0aGVin2G zPL3z~^TkE9PO1FnLu%-{Rr4-c$yp&0AQUFq@2tP1LGcJiV>FUR3y3^4K zZ6PV5!%zu2KelJHk)R9C5$=4WOt5Eq{x=y3TemKJNy$@b_Jfu4$l&Ss`jVOc=$ZUu zA^?FU2igz5iDZgD8HCa3+oFR`nW9a&zU8z_@z`(9mR@`S+N%DbU6+};LNqH?WXE3N zfuwvV@u!?ia#pm<69?ok*Zd>e^QZJ@zmOIBee`D+J|aCue>MRu2P*$vf7a)qCjN{5 z>{DQX-iP|XNq^?;kHyR}I%wvtlHCSWLTE|2nFNojy8Uh?UDfXTX|(1YuhgJ5HmFp9 zJoCYHV%F|&%Xaw?@fQx)3XV06A<7KO)Px=;pIuVhI<` zKn7-H22sH~f)^;%8oUukVCy;D)dD@nj4pw)niC{_X}%yB?L zEd)^J`>lP>nVCRnZJ+P^=ksaFnSEV*@3q%nd);=uIWlw?Z%BVl5+Wupqw?PZiqD+^ zvWIfY>Jq2#_RXN+{ssV**MCl7S4BKp5gA=W@FtJtUTi)1sD&su_ zA*tk9vCwcKx|RQ_sTSZ(5DBv)9qlZzxY=@p{L?+mywQ1*P)#m(UQyszvbxZx#1HIh zh4G(=Zya>xFT-Sg+Q@g-M@feT{V)`76Ej(F3{$b#1chHjm0RB@Ibg|BX>U(_f*dXF z3{M$t|nvdvw73f)Pw5(?ifeoXa>e26epGO2Qo$P%d!`(n+?DV4V} zgLz13Bx{!yyj-*|8960_u)rkuQcMRA65i5^G9dD>bLCd#_v^#G%3rCvFj1zodhH5Z zjwVtPP4R{7E)fG+7t#K**A#caZNmvpU@HA|(Va5PbATB;00@;$-pg;kTXq7Id^?jY zk>9PB-jQv?0$f-j3osX;GxckZf00jr2mT0}C*~bjW5U%a?)Q-z32vqIZMXbDE(>Dr z@hG4Xg3Drl7W3oxfKnMcolAEatxK3U+>`(nyGWKNQQ({u+kQx{QT_~Po`Um5DQ%Sh zM*Zf<|D*gqaXm;;B3r-Ay@Zx1^c#1m$VZBKd@i&Gak3%$$Fc0d>e2#M2^MH3X>t;?K%$p)=5j~{IP|EPS&ntS2Lu&$2Bx+nZ{%Ce$OaBCE&=Rb5v>$v z+jb@Kh5wXI#Op0sxC``_SASVQIdcH4>LjQqRvW)Wi z&cu&mbduGVtYpz0OqZO$4t#}n44_!&jbN9+IEfeJSF0m&JMRJmqqCyF65QhK7jHqE z*}YU2k)+WU(?|q6xeV-=R7b9YwA>!RtPF-!zPxomH+oXq4h&$9fSdXVwU_Y z<)>nR={Q-G4FsY-ZemPN-6;(N);)}ZIgF3FRK~OvY|Xr%EsvdeKU3qiq=g-Xe#6j# zNNh@?e>;^ekm)ls;M)~sNS~X_;h9qQXT?sNSo;hg`8$>&*aQFi$N9j|7JAO?ps8jc ze_$XqslKmO@N<6aqq)VHVkMB`g`bw$%ix7kt{a_u*uEu}X16QlEi*Ht^Ox+&G%Ng= zpfX)vtrfyv;;rUrzfZyice_Jo^mvJ)!-ZNj$wt9U)^ogCA|d;b>mR*g5&h?f$YNx( zbGVO8fPZ1a1eQ)WaHx#D>ANx`0fm0-rwQKJY3Z1rj7JqE&}a{DlSn@KxjER=s~0NW z)2FKP^*Rk2BWKdOQw7pdyzC@<$Z6-rF5^n7&4KYmx$|3DU7 zWROPr4JzR^Dn4nHzsb_ad)c zuTn3So~hQIYWSr-EOQ?fY_sTLdc6ZO9nSrSRiu)2|FQSi@$3B#)Ry}XOY5xn7j&rB zyMbP$&!3k`pC9SgdS}Q#otRMSKnCk4`D4S>0kNO5Ld;=7$BJ0J5;_lDT(v8?YR43p z1b3#c+ThPgDM}b;B8=i1&%Hc%xebq>bs?EUVgh{Nu9p8E^$NIPRcnBG)O~kSq#;g|Z(`gQ!^HM8w8WskY1; z1Ym0zyC1TL5&VWBWW@J8-vLiJH#-XBZ)KSUydJ9YZa;5-C7-T+R>xR7x|Gx4jPG=$ z>6otFn^PkGe}mvE3Nx%>(FQ4lNukzYR8MNNuF0Yuj5)D@_GSuIOzB|q9nc<9<-6T| z_KDI0WE(I%gDKE~neK+0GsFczMPUmp)J|!ML53^n!u88&D8=qfwjwX7w;&$}nD(CN zF#%6xSOc*V{);Q z!j;wScWZwO6l=AAU|CS7?q=I$s8fGUYS}({S)fF;gMZ?ugtT2jXVZxvJe96f@q^c? zg)JH(8_yt&a0Sn>cv^zp(qV0Lv{TCJ2(%6wJXVinUic|aRv3D3tRUZ~2L=g7_Mk$3 z$O-BDTej9o)UXOT$38$z%Ha$7r^%xRt3_v$6fi>Q8!#ZFtHIc#brENeV&vgbWvhY| z*BiUJq*&Z32*G*>GApcCZ;O15Qd|ElS@ct7dNp#^B6OeC7s_BQQxdTgjmmf}vkTR+ zWemSB#{z*&NWx?;lr?BG@E^nSD`UZBdm&MiU>))NFFBTh0=>#ME&34^1srjE(xP9g zU+~p{WCgZ1@8Zg<=+)=YE7Qy3W3R<5S(;;Kt)gPLC(+lG|9fFJUCOA5NPl z%am3ahomtv;E#{PA;lDn(T)rgl0~mW5!z35?N6mEW8{d7rGuh#Y1xj?wF1;7J_U#> z*dsCY-Ho0SmnljpDr_F4DqL|Z734V`?m<*Aw^(soHd?t=l6#uUy+Lx^)qUr>J0wMWZnMvDf5l5H{iaMGqu*SR z!)LGS_?%eK#fNTe;o)TKKZ$9xX)cFP~3n{UfdVqJ*`jp8i>UfvGZ8^Sv^BKw*ZbV)NWL5|^c#fj>p)lUe`U|GxfsBd5T( zuuf*(cj!GZ@}90aS?a+oZqc@}*+W7+7p|8wu*Nc=+qK1Cv2Lb3E5u7K*G<>`)_DC! zPL3~9muoLcX}yYC?=&T6X+=h3!q4GM!Ce4`dlo)k*JmiJ1RpZwpF-IGBl#yNWywEl z6(W8E`R55;{5$z4ln(hP?Vn8ksaVTAap^W?N3FB&r${I)zi$Z?d-_yqqplYv8rBDt7` zNl^SAZ0+)uWI}Hrr#HVb^1)t0`Jl?`;T*^mwioh{fl>ZrtK4IhQzA;$AO*xYEEr+g91?M+j zYEVtvv=Td?@5yX;UJXqa8!=@d`8+@3zkHV&NcAq4W6{hH7QLrBrTcJ3Et@Qp)%o|g z$XwvS$^wZP^L~~%@u+o~O%`2ZZGw1WfUI2kgB|lfqAqY#QYg46%O=wXTN5`26?Nwr zh$kXoUKn6*Y)3mFalatq$FihvP1yd=_k6MapZEDJm-Szw$MmIs*B;D5y%oIks90OV zCX^oW8~uWl0l zaL=(o>4(9KsMpS3!LI*(tA3zjcW9sAxNSclbGjt_>eKaZ#(M-P)!Y2~K7ZNYefmaU z=_i4_PXe)v17&~r>VNl_?(^sE3!L5HJNuJBMFX~%7(eh_M4`0S7|_4;Rcr}fCf%p$ zx#~ZdZ^M2d(chXXpV4cCmj}=zds&U}h~AuWJNZf=;3Iy;p7^x$Fyazf`_+Q9Y?INJ zGpg2u5)ywjlRHvws)|$NY&>J2;#s5`2&il$KuG>EOvR}-mpxnJdpP`uMf(85SNDef-%CL9n1mzfzlbE`%CZ% zoG3hHk89UrkBQj3uA4fMXl6WExg@c}@JQ5{bslf(K-)$~pTc~T-KcrEk z+f)6Ro#O(W+hifQVh_kPG`pJtnvc<6X5#fSYNOi=1Z+5QupRhY z($&aGsVindiIQn^g;UoPuvL8Ual2&V8S(_VN-*U^K(@mr3fU@eP`G*DjdY9gZwcTe zi_T@8m2}k7Q=BTN%$s6A3FEk!l~t11?f6qLED=|pd$zI<@LK#LTtsYq$-(--_O$Wj}_%OZMT&+q& zd^W(7Df&~_j-5I=J2pat7u%e;jE+@phd#Bhe{y!rs(%76w)5-k<9V?ovRXDT=2m># zi2Uljg26n0T#%dS%|iZ_N({`c2If{bSJg0FnJ;o6`vit;MMjHaA0#Sjc_$3>whNj0 zOaj1y?e}8qj0#)j?+YH6ug=G`yy+k0JMyN#aaOXbO5Sv#blHJ?aT++0EK1U=BX7F> zdchJFUhD@2DbDXN2Uu_}Mc@ymKX=Mrat^6ZccbX;czem!)}A=dUeYT-I&%F?JC=7r zRQw`sXfo_2drJ+Yyy-d{w$=12Ncn@a1h%bn1U5_lX6bHaMyJ58A?60dVMj9L-<7#|fc04^%*kL>oJQwm z3LJQ8Q9nsx`A`l6wzd^!p**4rL1JcySh}T|@rDE(74PLc56A$*{A{OxCYir05BPxe_IZ|t@j~zh%?y9>r(bwY5X`DZupcwQ=!LA zpioCBvY3Xy8H$9U+v>XYuTW&FDg=sL$%1F@e%8C4eAha9vC6uL6I%2{w=fAo-kjjI z!g9;r_ainB2!5)6_=S07YLAX~HD+g-^FYr4b(B1Knc6*sw-qtZR8ggQxetMZB4U~< zreU}k@(DTghIrXXHk(J6VACv5)0$gDX5x$oTd}^2oJ?YN&LMr zfGzGE>izsZp}S{YqG_wI%ZYq`f8It}Hv+osvm7HtlYPl7K?$(oMw*b|4TCbFtAPLr z5I~36$+AWl2=_@`UD6rAIn)cpLY5)evx0UqUGiVplH?hkgZ<^i71&q~I}mcPq?oOI z5aK0Ac`?P2tAUV;Ezxp>0x(kHXb5_&96(Q^0?YTwQjb2)sJ=0qz#JXK50W@N}MMB@73}H^Jc*8dXq_RuAhL2>?#|&5si5vxonl2>TTR`E~G0@1Am;X|T@_j)p zZh6x@t2B%;^2}57*GSAs%$;DUxLjt z<<}>R9(GVy=3s`b`z%_mWrhUd`cN@hbe=Of(T@1_p%MVauTL#(@1W5U;vp2j9{|-& z*sl-CHe*Tv$f}+^m(xFttwdd4X?YJ1g3PPQKL_~Wc#d_z zx>_-hI*i6`>4A-IKb#;_+3wW`tClig%#6mJm@Lyes|z5>B+qNVmzm|xD-;M-_9l{P zpGw?ea9{S!PMY(>U21L(Qcgj?3kH21|WEnQD z+(KbVU2UZ*7_YF?e(j`jP+Ury7z|w_n`~Mkc@G(PD#F?!bdfA-l-(j;Lq_?zD&bixp;)A)BCPF3 zs?F8@oGiFnB%n7H3zNnypX61qIyA4Alu^WQ8D30JSt{B1#SDimC#Iux{~N!+b7@BR z!qxsjr4~!itWaAInT1i`Rs6m(=t2%_1zfzNj}u&{6_j!KyOa8R+(WxeuTa7A@$vy5 z%U%>##BfOdCJ;gx7x5}R-M5gd4b0`@cR5j~SLySKZfO2eaZj*+#7&(JN5vOWmR^ts zAj+^y&@vUgQNDddLKcTP8;(E*I0AvRzr`NP1AGieD%NTjO3w z@_b1eI^Ho+$Gie0GELER0Erd|bMo&2QSCpW@xr>qZ8!ps^o->j})OaYg}Q+wsx3dHA`7l$XZxTNb?v-Vab9$7`(sYL9)&#?jp z6f#!HSY~C&-Eu-!2*KF)c&#Kc1@POS+-jAYO_F6_iM*<#{rW5VQCEj$d?5D$%y#?r zY)%1ZzxEL;+WI(ZgRQJ1+Z9`W^NI9!oeXI9c2%DL|9+SJo9!yQl?Qz;bN1^mfv(+t zjX)r5=(O4k74EB@^%ld22b2BUjnr?tUq527=8V*SorWaX+y?~qeywp@{V(?G&tVSI z`*k>QtNr>H1#`FSdi+=W_4^)K<>RgrVE{g1zuGgI-mozK)`r~=D9*Y@2mN2%u-~o{ z;H(Yn|G52zy#Ng=%Igj`>}*J8dc&Ryh5UvacB<;`_zkPL;FE0FLIfLZ*w03*4ZDUv znHx42Txh>xe+Mw_H|(PVp1omLsPFCZti0nk?37!i(DwMATkqBx}P~*rn=8 zO4&nCZFjUDqz7dWy^jy%)hrye>}o}JJBdnKbXc{|u>9&cnC_CI-{AXE?koI4Z3i=0zVRv&^jhDtrC?KcuW?F zS*8TwRIQ(4w{ATKn9{EKOVZl4_8KYCu3ZczOK-Inp_f9^RFny$+um*`ZZ%FA=af1z zz~{hGvVQG0nbI_k9>ien0H5}l68&UA7pVbZC}E98&E~_mOCzE~ooX@LnX0gW%H+n% zwBM?}x5uCFqMQk>`$LBOQ-$4x-BX#kmfr>p^ zM8q+E{jiFZLP=v@pYXgv$l=;TtsEM}N0Cn+)x*9F)rl8xcG<0kOyH+1y-Z*w%fNf* za+Jsfo}wDWfEB zuMz&ir++OXwnnjtU`>iuq=EwyS3o>isM?Dr&;v8p++6Vx$3(Z#oFa7I_9G%fh%^T; zp!kslUI*fEYb(H!d3K-xw^p!Hs!1=%T|ibbd|-nU*H48aEXEH~DIB-Q<2j-_>|i~; z633p^oR0ShR#jtwS7bM_F~#yR*dLqIr)*o7$XetmkOgq$9# zMMqgl7x|2W{)7ukx3tm+EVpaFH2^6_t#a5_J8Y}J>f+JW_Bn`Vh2MKP_yoDP?J(Yz-#Q8F1 ztV7fbTChF`+S@Bw<9U)oAcTK75h%5&=!?C>g%wsi*Ka(4^U{65S3#izq1U~!zWfza z(0X6&N}!aUhqJI9;s?{ah`+tu$+@v{9qd zLJgd?KrtEUAg}IbhMVQ~foF)Q#Jnkux@|A~N~H`#WQ)X2!Q8>d4-{<*KhU&QUN5QJ zvqm&R$HtltU*8C0_aql31#mCws z_5O-?w4XNQZsaVMGATTn~v|qj!ZDh`UNx<0<`qUgi zp>%u3DD0P7+x$p;O1A_rRJBj2FQ)dY{u`lB{f2M9zv2zdm#&ge%bqCUYO&-uf!Kt$ zK-nie4`Ul$1@xnV(zgP6Zv|q7WCTjz4dlHWIQxsh*+&BvUxd(WiVag;p)}dxV;fhz z;TIz6kM%1F)+`nH#e7M@{(0iAfa`S?^yE9m0ew%Pbi20b6ByM%#oOBA9m27S2ErXa z+PQk(6~+iiXHaMiu_D+S$Pw9g(k|At?A*fI4Z?A;WOS$1{#vTXG+*hPURSeUADF;s z?%v|Yv2GWsM9s)0M|-Rx|GLWX5m%@)h2#YWE6CBH)HacqFpHiVh7q)oJiiDkZ=IAO z4;6WFF}8^c&QE~1G1 zUzT<%GJ+Yd>7pTVsTmp^pD0QUc-D!8+VJUHWZDMDFSirDYVS!+^~(BS6a?{eB~K@Q z56=oGm3&63kK?p!?ksGgu%x34Ma>0khm@YgL{~n3kdaH6^whJl7K=A812KdTBDUhe z;CFqIW3EtdY^n=NB8M*s-l(o7k;4}TCnWB3hewoL5Sjv#`;0M3O6D-9vu`Zh@N_<| zMoWDaZ)nl)(NC4$c5r8so6|(jqpcoM;Epu4xFgBDxpms=&92QxuSeWj@6u$IeuPkO zp>43XDkig>X2o&g-k@VcFew%GfLR;ht=$)zVRMH}oIb9wYRUXQRZFT*Zyep1V0`8_ z*=$5*E|#W5hKt!~d;$&0oLKFURG2`lAO`Bv#xQ*jV|t$u1MPjTJ#~RDl@G}+l5-K7&w^K zB!!wN!|CD*o$Fp@mDEYLEV?k%Ql$x)lx0eYdTFUv%-y`kwJuJEWIzn{59er$#EXJ+ zWmSGz9ruxqTJ&oY4(@VmOB*@*{wF{3YD?tnJZ*8QG`^~nCyHmATv?#{l{oUeZpxd- zmPY_e_3Em!%^t#+TJ}NO>YUz@x|T>A^Hu&wjB>c$#5;i{}UBG0?^I&a0M(7Q{z zI?+_k80E?~xc?^b5R4-Dk^A5dfLR9;_v-GBG=Km{^5)*>UI{4MLU#$`XSGznleo_U_997t&OYGc-vy?#MtRWm&M(4%+u>=y9S?t_vdAMK|g>NqDPT|Q` z;RBbb!VlYpyW6oPub?pSB{nf>i61ipp#d}!GmCb5;L>*bJCfgP9DR%7DV38R>^l8l}uIJFt;|kKGIgGMRrq2TYa^w z%D5s`2q%)3$dO?l%21X<^%SaW&2i_}&8wo@e zVllnOdrD+f!sA(H!lyS%w>K~$9jEaM}G!;rAxN#i0#@#efRdH;~Y6!Hl$bvtuBxo=f1 znY>TU)1v={e)=MZ>GqF&v1@bu#+a}CIzcAKO1D?B;5X9dF4~lyuaLbVjY0+w)2L7* zirtX?ufThgLhia9^t`cZ$)r!Cbp*Uq{eoDF#9P~IxS=zRN4&b)6x!UTxwtnjd`_#NAQelgln+23q# zsgbrxzWg9I$+Nk!TQ>=+eiwYMie!5;a0-IDl* zDP!Vy(#FUc_lfrPPq0VMtRFCPN-dADn}O;$kFem?4BRqZhj6wxL+%z%V29UjkTn*} zkUa~nGfTA?sS9^#g?vtCi>dpOnom8$CYgxG%b4es{6^;6iD5EVaK(yY@~C`v7{g?8 zaz~ooS}J~6626BAIA>xFq`Kp&E3I%W*0mrBq>u&3YVyS8k5>=vZ}POMPot(q$=KpE zhmjFkKX@`hy{rZ}=Z*4*F)vpn5QrPcsw+qp_LBlH{7{qUD`~|Js@T19N$4weqc>|w z)%V+h63?iQcPXe_;`u5avM}_uYBVv`4wX2tK3-7JN)dfOg-b3k2ruz`ol*RlB72Fl z`gqTR{dTbeyI4k*V;NPFYL|LTugldQsmmumOtan`X+AdsiP-9i+kLGL7amL{5fkeym5f6&HmyFMMH;y?a zKXI{)=AJ}f`7~qiJwY)owBOWm&SHmjU8!Gjg4a;(^#*~H1pE=j>b3y*&0>Yg>X*lN6$#>r~^9a-Iqn~Pg2 zi}!1_L!rJME<m_*>J9|Ah2lE%vtK7XO3e7XKf|E&hkcE&le@;cBsYQq85Lv zEPm^Bj&IhUqp0hWEAt!2o|11$Xbx+CWXcd{NLW{i#kl}RaE`jx`(p&3Fv_pl$b7R9 zvc^R0SLS-l)lbu}PiuBR>ym?9$i>0YxHR_g8a2&Cg^fQzd~r9=7~Vr0zj`g*MsgE! z!W$Yr@49&Y3u6sA5Iyh8DJU_T3diB4bq&@W>RD8+G!WKGCoQD}ESqOJhvNl3Ih#X=?Yy^rN{pUToOlXK7--CG0sQ_2*`w9uQ!9zGcvB_a??(} z={G{niEb-h`~r9qg3rk)SGwE>Uv-5{HN;DtMim95<-agRs?n7$1m)|QD4Br!(G@42 zbM7aMRgL*S9q;f$YrN8^J=|g%mN~zcvBS_VXMtBZpbWA=F-K(N0bvhWMA^=OX-)?N z6n$)OgLUCy%5rs5sm!M7CymT{1s1 z0R9gH*3^|b5Y98x7nq%8)-Wq{RN%?mSfy`L9d)9k#A7~Ji@&0dS+9c=`fds03PJBi z;uMb&%29NAM$#Xxq+TlNO|=P@k!10A`@N;dxGfh~_rhU2*qhIs>Ruu$G=B+5aD9fG zcUS8suhS1icJz~IMP+qF`YHN!tsM3Do_SFH{cOYZrP_17y2428)SjEzwG$toOxNz% zIbECj(dXK%kKTs8kbk!Any$UQo*Z(g?jz^pb~&%3NzDPfLQhkynL72K@==fdz=PZ@ z4+Q&X+<(e8hev32+T#r}o5^~#9ihF@vJ``Q0zHFrp`o}XH&F4u_EQMJbiBQH!pP*- z2XonK=G!cSKh{NCeeEFdBG|h>QbFu{Cvg@}VrO!?M%D>-8=^$^Ecd?XC}w!Q+ZE9M zii~0MnnX8;L8kH9Z1xsH;-jrE=EA7W9WFga@1PZ1JCre=F++#sSplMzj;0y?(r^l< z?oWQhZR?kCwBLB5e#xr;6IM;t-zfSeFZ!j8=$9tSXNUTwBR+jwhE|E6{|J=66UckV z_kyE53!ME{;Os=8;w@1zHP|YqjdRvQs5uq3~7VXDsY(J@wHiyon{puy^$p9+(bTDvIa{wAaOqkEo7lsfoHFOY2F zVIGlLfFFo5xpHXVy;Q4Rm@j)Fw8lF;u)?i9wqA?gN{Wi3wS*6^af1t4eQ#}bgU_hp zpi1gnDx(MQzaVjQ3SW`mLAM$_`X*5ZAmqxMbC&t4!i_Nh%3=P7lcOzGhfM_@c%?MY zK^45rRT)0ER{Oyueq+uet^eJvbLzDA7s)hdv;Q(BRixPVIal+0;$^l_Q7HLFk|E`D zp_ZyBw7eBs-l}N12qQgtn>=~-ZlTOQvO?#WeTpd(OTaqM)K>sQK|%ylGo$=&dg>30dAlJ4Lq6aC+rBvUP277g~E-#Oqq^*PJyd z>8j9JB

    y_0=z#pO9qp&%l5_j*fa%|5Wrja$FK&BRyW)%|c|4#9mvxl6qGf1;5cZ zk2gxL5R-_CrqDlN--U zhrf53i|Ia%K4|AMAWM{3{41Zv?6r~IA0o0f9uP^nHu_j3iJW|qOkRa&jTZeSs#9%s zVRZBToAfP_-NFu3f<&#ChmUNZQ=zS%2L>T^-osJf6h5+l_P4dw6S5<_yVmdSS-+~CE% z*m>~!)Aw;Hceb8Z+nwgd5k7^1cA9<8^o7Hxl!VT3#(RmHH)5+K*ZGpKEBlE+DF#}1 zFZJN^0V>~;uOQfwti(bWaN7^n5jS!5~YCSN5is_dvPseS0GdqsnjC9qE@lShx zQl_^IntC8HQ1ypFnJaRH)}NH=-Siq|D7yCL*5a(4E-qaEedpE399nm z)Fnx)6-8g-43e|!_aJ+2tI``(`fa3J@JdiQ2|nVlII2bDVhe(v1@7D=(qxPH$>SI4 z6XZp_xrOFH0!k@Xhy0mH){H2 zl9YhC(X+(mT~k7W{Ga_0_8KpHrKs_&RE%GZ*|0aFl0d6F5Vd$?#sn!4ISfV22Q1|J zE(d^`EC9f(n1Quvkw)4C=q`2I_pvY(%G}9pl76famTk5N_#$bT2L}h6%V9&c+DQ~f zg|0>YQp+lwJ`4Q%QQ>Ms6!n#E_qjeaNAL-Pjd6{jcU(LqvfYvuU>1i)odlHz;k4S% zkfvwi_@Ym^*CVdbYR{LZBFXI8GKHOh_Gh#~$em+^-sxmwM+8j2qYM|tfR5f|KSpz% zf)#xGN0)>!>{4y|5+==P0B66EmAhpTl~qv{91wj!L`DNxOOsX>}@Xyp!giNZKD& z+At?=tfc)!rJd)b`K7&uDy^rJcD1D4rP4&_3)B{{(Q8<9^A2PaOtgokEFVLmNZV*F zx`lF)HpVlCT(5Ce5|f5bJ{Pf!ni8cB{cCa?v(VuXX6}(jccktKw1i#UuvhNf{aW;I zv{1R)<*)cmi$29S+psGaiu>h&vu{RI*rdDA#J6pqGn(w{GA~A??w?&r>ezO-BB7n0 zycW($WO+*KGoJ7YIp%DIy-jMLb4&7|{+MDVp_y0r8IRs#`bkO?rkKrzU{?tZF%L6c zJWnGFTWT%z73`DnP;}!D0Y4K!0EK!kFGuoG-OrwHK20jt1=xY$%1u$#GPWS0sb(QR zl`fKrozp3@Td5*1paXti3#C@1{d3VnPPG!p*17tkpG-`&=B4}nDwx@40xM~DEi4_2G{3o}4lAVA(my`|lZHnHT1XPP{3vxr%V z&MRHI=k1v1?F^3~^`5C1g^k>Jn&=BZKr6wIk9*6H?H6{=dfK(*F-3@tk@qXth;F|x zQhNM+%6ko!XKV7qmx^;BamK#JCg4R{P=i1~sNUr=lSO~U{)MbHWLc?Yn=$()ego-c zn-f1FuZmXF)d-nYpDdbZRomfII|ljH-@{&+bo!&#Ppm9%4j7QAC(Np>I^Ae4(UlS} zr7CkesZP(aN}M4juBOD(lt}paIKYPu0>-xpx7sds`dQ7;6Zux3!_vhVAi=kGB#Yjl zBrP0jm&Fa1F|M+*)=L)j-I@R^YZ+P2{h|H+dg0y~au!Iaz^^&p=CMIuKnuYRCVs|X zoE&0-KHNi=D*7y^E4<_~Uc8k%%W_a(3h;lASUpiLY@eN4w3C!|al1OG*pu{mtT>E$ zr*l#BS-Ll^R_v$D+vS9S-*OndH0!~=;eJJt6odDsFdlxzbex32dzj`RF*$bop^+x0 zg_2@1dv9R9V)Yz4*Mygo9Ea<3K#HQbkt=*vR@Nx}(Pw2^*bBla)rx#MalS7WV%U?o zzS&ZC@#bB)UM4dwSx>eye9m!Xgp-#0MR?>{a)pueEYL8I9;6KWy@w=qB~%gZo~L=d z@uz3+qO&zGsa5gRxnJ^9cum-<(egrH`FK(LWO;Y_U)e$T^OBOdDm}lDC?iJ<#mh8?|NOH77l0;Y7p4A7^B$S7OnPI(k?Poo1Amvk4zroInu>TBx7L>N;|oKJRrSB zjxEp@W2>3P_0Ct?Hm4LLqpsRRKeXmVNxAd3ihm(*{aADKMdB=rKVFy&Q%YO3fPc-N zjL!m#w+S1(k)3T`?XReeTs-}Uj1X?Dm2qrk7drc&pwd;(?&V+qvtJPv&;Km*)}!iK zN;dK)-u}>bUqwssJYVS+$DS(|eKrV6j?$ynJ`kf!Y^5vO=6)oj)uW1PSj!-iFSaX| zQ_Tu^d{&yFrH4Wghx$aG{NP)!mjQ|d+QNlke^pH30b;?8Y?_5fnrTW~bP+u#&X9UC z@yBKMAQSX%fB%uL5A9-EIy0gYf(BoA8M9B&;N9j9v2cxfmic2-2dmhlmJ5DvE6Nov zrclg1u$##irP&LO@x~sT$I{Dt5$8!(EEML}mV66A^7$}%?~5%zKuR@tato=wtWwLt z3%TD($zTx*xf2M3m<0baqdIG4z9JVeWAaPHZ<+bFxV6_T^Bcbv%F}*)?pRKV?s-WW z5+9>qly!9dGhbwVj_mEPLLVl+k0f~-+QL`DK$k4K4LY8t4=MVud|;)7qW;HFTIU0j z-?F8#WN`={RNzrwkoq&KEx$3Xnf*vG(qr-3kJVf@L-&JwMXJV|RH7N!>McdT*j6}K zOzLR6;u2L}=Tnt223D{Y zRI-sj$m_lOWK=&^8pm|+Oj$N5$EdVWpVwB@{Ieik&Zb+C}td5B5iug!EJl z=al6_xw-;(pi_4u7DiYzU zJ|4XX?eSk(-IA`8*Ok?|Utou&_zS5p0aDy6H+*DDa6*-FV+*k6&mPDZ13B8ax?8y6 z_lY8By-8lHlFtY?>~iaG*`4?f?VOcIGjE|LsQzQ)SQmza(wzf?#7r=i&(Bz%gOD7X zUdem|IKUG{zoNPNLIwl;S=FI)k*0I&A76-?t-1sOAY(dHWI!l&+22_u3JC zt9#?!Rg5mko7cQfZA#Q_e1_|5%QlzQg%9tRqwINEQ8}Qz+Nh1HXvTcXYuKRgoZLX{ z24?Sz>a%++TI4Cd1F;^=R!-lXmJyuC zkC9^6fH;mpBK*9_NHgZwU-6+96$3p{d-e^lV;khn1*26j-a|XIu!zZQ#Mo?B@k8}i z-JKQfJ0;ZBE{f5*I^@rl9(5nMa6nt!TYdolDN+`JNFRQaQH^k8L_WWB`5kb*&jmYp ztIrtHNx25Jr@v?b(BcKB`i)V^@b`Krr*Q6uKH+%76DbRGYrm^Lc)e&^JxoxSwF~^F zh25H!~qDDl~I<}B*1@-#y2L@|>F4}!{v?Kxn(UL?Zne9z<=7#ES zqr%_o;#&J4XX};(+(9F(Lo(QhO?_X1TzlRnN!@CGeLk0-gD?Sp7gv_eK8*Mv*1f&b z?UiU;{F?&J{Z}}Bpi+Blu~FAeB~fY^vEXmU18$J zvTf*x0H`k1E#Xf62wtkKevNl0d4iyUW2AEtKmzN|UuS1UH~2KqeiaHD;@)zWtluHM zUYX~JO$Lx;Etw(@=-A^~=bTS?W&MA!Ugy4h!g{@S=KquR`cnI^*K67qwO-%))$!|9 z45Mr|f zP6uapo_%IlW;y4z7Lg;vI7UC(h&#%`t+U=idcAp==dEhtla>TFqs{HyoOt^<`U~%U_gnlk zZL=jG2~_N@J_Fnd4rs=7uwBE!U5UO+71VSIz*_A%Ir~cZ2f;`c7u3l5K520YZkj1! zO0k-r_W9y2i9g$M_HG!IO#!{O1+P~z@V^4V`oHBMm>4L(b~?U7&xuWB1&Z+C7!NM7 zg94?WR!^bmUmmAup-hexT~1NT_3+uxy1H?z%w@ik_!_o{MQ(6E7kgZV$7t2sjU+kX zT3X_g-?zH2JJNV-l^$A;e0Dv?k-YCy3_QsH|40+pWi*j2I@{|05&M;$ZZjYd?uEzX z)tuS)uI(jIzLI)i$2s4W5NUV%eH{1f%x3F-9h3KU>Um$Mj`wxyyvA60U#GxF zd@=vXIzEX}UZq!!Y~U_{>`UI)!B=$d9~0R;yM~bb_BjK!=RU9hwA0Lk>XDsKd)#^K zj?yF66FXN;*C%#H<{(e(Na6hI0`iOmfOG3i?3^gGpT6Wv`0%$ZuSD-V4XD1Kg81eQ9Q)!FD0B zok!fRMY~HEcE4LJg&cOsSb<}I3{Sewl$~xD(4wp4hf#hp`3^nJ7)ElyCPcwd`ZbqP zE+zkAUaBWR>MMlQe-B4Bu4jkyXAk0w>)GMH)!l{E_fC~pu56NS-Oo0O3WVw9O(%6f z+obMi4$P+m&P_kJw-oQ+0)U#IPDIfx)=QIRCH+L&~~xOVna+S=Or@;i14NFRFI6bfz; zaKYYSOxgCR*b2n`otwhUExnj|A$njSGnR>TFQTZH^dmG2px=K^F!R$yfBU|dS#+sg z^i6>|iQlyf19&`suKK&+CqXd4PjUEj##PLc{g}KCakCr%nJ_a*1;%3`sk+aCpVx3< ztQavxi^`R}3i+}^(Q_=}Zgsbu-{ZI8&_83sS|q;J#W@HMlztB6#Mnjfv%sgn3M+z5 z&8yWb9H`C&sx?1Nq3EAaO-+<3tB!*L|5<37RAMWp(R@R)B*4h%LIHZM`f2Th$k$)b zeG)WCV}e%u9l_pxBAv{@-iKdLVee2n1$(j5R?$fB!lH+_mZB5@fsQ^)xRW#m^v1?< zzaN)djcg~^6ReQ)z&@6ta9e?7$H_fLD%frk)gg*l3 zL2m#QmuZ>czObZddr zUC7Nww=m&#ghmwOPH~E;D6yldy#exr>6J|)&Z1(|BPoLSQg>-Km}?Cr(f(lG2jv7! zycx$RtUlTs+CuCc>?daqMqTBf}1ipkfD94*Y|2$z?T8xqdLV~l+T3zO5d#mmXU z!>_6#JL^iEFmY>fCtJN0N3_TrG#Vb!gPpOSFRw9+ZBPw!drXU*N~Q3KGML*uzStoI zW@Cr^Qp(wDFNfWsSM8}KHcQYJ+th(65Mg<5DIr%}5+~&P+qzEks&vk~~7r550 z11^hM+4=T1hCY9fJ@nenq8?KDuaobOO~Z=QD)SW612K^K89|n>{ z*;8{38|jlpcjcwVy;-I)%|M!BLoP&7YTPGlBm^^AG%Q_XIVIfnpXIv4 zdvKg$T>x^){9LnEYFc|(i_ViD+{(*IS8lGB(y++t4Oo(7aRt%vi(#Mo1$c^?DFI* zJP{RVu~hS)%7;<@UV5J9+Rfu@4m>tF5GNp-UY;x(WH()}vaP0TZ=z}QNmXX#^|X({ z!Sa3Tt=UZnB*Ms~x>rW3nfy6SL;A!Oej1BkCG-gr6Lc;IDjH7&K4olfOxwo=FNqxS zi*~mX?e19gll!a7(Y?8*gf8Mxm!^3#%&Z1yGV6f}o+C^^Yy z;U`zw+8jE&i%voVMbi0Zg4Zav1^z)VI8(;kuWnLtjJ)mF&toTwjK;cAZ~gL4C1aSqbqwm+hfNhgh`a zM=vu>*~9>fu-76C-_BvE_C6BoIBPFOaLQxvPO^c!| zVB5NdrM9XHMfvz8Amnsmr$0bdPN^HIW3k}AZi>V7rG|bLB!N1QQ^&lXN=`!}9-AQz zSqDLx14E{G44aU&Xk2D1MQ|>p_5rAkeF%Kf$sR$d#k%Qh(VwfnWSx;2RBX~BIthpk z{95e-$+9E>?9r{lqxJky7?rK?Am@@P=Lk`TZ5~Z*`P3@PnCbUvm{$e0xl9tQiQ(xl zCY;=x(@;%zpwenDwF!%o@yGbpvU?&Cn5y_Yqy+l9}Q82PL!jka|62QREkaSCQ;|%=tf7k=B?FxvnLamBH z`Gso1T5@3zzm!o~#C@^LqLsH>Fo*$E5H`;gvvX&01&^-;^X%oBNEI8*3vI}Ie4!wR zv}?7eOB&JbLIYEisUS7V^U`e;+THHWJaQ#03tjD6lj_REc-(x)#^TrE-;}>zSrROs zpw%k1wrt21R>dM2Ru{favByvK{$t@Bz}YCdLY0z5kI*a!MD%`g%$W*=P%DQ>@KRZZ z;O^8i1k&IIW#XPrk6^sjM(z0&0i3IY=VeaU+idP3cLqMy&f^7hDhK8Gu392C*kexf@1BJFr71~PZ zCwxAaDX*Zd0)C`sMHZ42KItv=Ge@*=Hr@2+&ZV9T$Cou(wDMTGr&gg^O|@R87bsx4 zo>kUu#l`7_Q|M<2X3Z^Hp=w?$G-ME3;bSw@pU1_zQ!AZZN1zq1 zT$UUrT(b#+D8{D<#f1?qX4bwW{H!AWiV=N4H6J7vlle!5Ef&d;Rs6dYv`EH8N;#_- zRmGI7_q#}V7f}j?=($`3YU;K041VJ{dGFmy-kYH-peYsyU4fFS$q;0(bZN7M`Z6+G z?z=jz!jd2`tDXTgh6RE>|5X|^Q_xC@p+l!7%A6CzqVFMP-AUiJ1iB|jNhnlc7c&2( zs-_3ueF{BTWc#{|9u`Y6bZiUP%T`NEmQ3-V+}-hQ2j=Hi4~3?_$%I z1xmkCc-kU(`Yf6L?3(3NB6KZnsdWHb8RDa>aJ?xS$QXnd|GkuqDPUD$@wBqATKSx0 zQHAkF52j}1y(7+yAUJg>V6_-Z|YPZ9c?w!AX&}QK2COkAeHXlGqHGlgRTIaNyk$O{sgM;kLPO zG4fg@4th#a#MSRF9OnAEtZhopKPZhHmYwI7@aORuMPzRNOf`AK!4{3nal7+xjG1KM z|M)Oh3H`7XjFRGwxmLO44)r^wTPfF=X2gh3{8Dr)@?VO-_r|V*XShn~=L*r!-9l}( z=lXkN_X{T*>}_v-_8g&+RTpPV7y6s=DV*riWeTLTna|UT0Tb+S7PcZqc!Cl`ILm98;IixNzliOq+ zn3Q1GRh`TM!sVo`&bFDoBq7=0)vqcvbNSAYr`q;1UQ{{pxgho`*N9G9^mS$yvjEm^ z*UzzvH>RygoY`*uL}Qa{FT)eEc081!oJrO97<4OR;0GmuE=Tn&WTkvDM?P$RMM))6 z&fo>I%s#cujA++NN8f&_8KAUUz%;%HeUdAKLOhC3{;Mi(Yg-!m1Okab(D2HzFGc*zofR*BNSjA$0f$e-JniN ziInwJnXC&a`o9cZQD>26V1Y`~lm|$%$nr#LuM(@9ZoVerHnTiS9?UJXHhQLhVU;V9 zNbklBe3&RVSgr{vgO42Ru(eq;1nM;;09sn0UWNGGovf=u0FPg*bwLbE*T&ej2-=5g zi?5&xg7(-Sj}x?44?)O&k0UUE^|MYubsahI=hT!e_-Bf}94yf2+pECV_e6GXN!R*H zs$x{d^GF!g&XSVR+6fmyjqHzZsT7=ts;Y~1u*dk0a*BlO5JW;mB zhrA(p)yDB6PS7fn)&r8qokFXM78b8WH;!XMK<`5J%eb!$=Nz>kE-8 zSyMPyCd-+^{c1&+!UM09%4O`aI`QkQH;Z}sCE6S;)g2cu$0Jt^IEKIcJ_XULbg4V6UNYuStDPWeYBP!IAT^un z&dh43+qsi=gj@?hY5FMJ5p-+QGci2fZ^pe|%~!8=$xf-a45?R3W>27L0Hw&6{$tIh(2WUcFJX) zF+TVY{)&8LlO$Mmv}g~DM(uwpRqxOI&tAw3o^uLh!o6FJEf-5gqnp#nU# z*iGZ)PpKFbx&^(t`1PVgriT46c}BUn;Jce>9g1R5nTo+MPF>C9u%$j88$k zXO!vMZ~-}WDrVVH3Kgx?qPDoK%s~oEzU&xrLjO@NsDXbjeHrCdQczYIJVX9VuHB0* zIkSRlC5wJRPGTOhDcJqW{&i!$*=gnmW&djSxbtwz{`J}n`&TJ^qWvo+zPbIYuwydp zkXOZ8z1$ss6_oh8Z}oMs`ma7O;&|=J`f8t&y>|;R8X|4yqD499Jq8*ZlB>q`kG(Xb zuTNxi@2S#T+fT|mgyT6|<+}F}y}`pTRzGf_&PnlI_;G*iawTdqSPvN1Tpyl{zNS~% zmE2C-+VjUC>iKfc<8BoZ4nbl-@)8jqm`$C0`h$hW{VgaO@(Fg*RAsmsp%d(+O}O&p ztN31pUJM@w?f0`*sx>@*77t&-E@!?d8N*!nc0f zN(|mbeRyXlEPA1r9mtI#-5%b@#i~u#CxaPIwmPi1Fw;Hn zP3?)U37eU&u$gIMS?6XYN}b}x6d&{(iZkJ`fbH5GunxU-hKzY~UAXgY!G|Ge|e2JPqJgK^e>2;7!Nd zV0fmt!5bV@%DtdwbD-k0>i*(bFcQatrsG-)?l3Q)sQ?6zVIb3yYv9?xOilOsWSZZH zj)U<%-%(f6WYLclM>z6S%<9=Tw{KF)$6vO{PMFkehZs2%-Xnb-IjOvucp2g`{rRt@ zsh34E>0TqZ9AZv3CyT;tsDsKo7^(2&7G$X+ehS`%+xrq*07@WTFGQLph)r5SECX2k ztA*Od3=!$EVe*s#yFB;njj4AJ5Jz24mOoZIgFm?76Wel4pp-wMy2M@hii_CFZ~R$+ z$&hcTYv`x(cb<|nL5a5H))0)VQ+A7h95XC27ver4dJSE)TCx2z^XMD>eKNn1q9QcdJ&>Ja@QKWJ;nurb4i5D(Xz z9UzM0g_6?AUrj%#b zrXi}>#;iH^&b~;(HM>&vyoiQmGD;wQ0q{oVB%rqiKk#NN;ktRX8XfBzo7`faDRT-V zP#dBen5R;Sr~)%8No0 zr_Unc1Wdxx;Ye32UR9eG73WR7RJCY?4>og8_?Y`&t8xO$U7-TX!Rc(D<0f}hW<)ts z_seU(X_U2&+o*T&IEY3 zTJS8ofSP$f4N8qrkOj(&tXN9n9MZ4NCN3voIaA>k8xp6J)rrEq{G&G{PT^NJp+xhV zB=8?{Rj~uJ@6fdZs|-)@(u$dQb#Q!m_|?H;wJK^hRro_SABjO~Y~+Vd*H({qNhG^^ zE*5^-J{A{}7^o_84#4(s(N6py?%oAHs_NYP&yWC7(Fv6ZsMVw$6F z_5dwf?=7cZYFjImB%)PHV4yN*oKsFOzMNCrm)=h49owpaiWx{qK!HRN5Gw>wm=FsA z3j`46{r=XPnM?v$+tYsj=luQ1Wbd{2UYBP*_w}r2jpxN)dU3gZu@^52GI=kiUOYH_ z@U(#IJHX2dC+?zGx3r=9M&Ko>Ab8n2%_(fr?}?2&kzQV8D*LCuz=G442cZDqr5RD= zM5YdLBDa+|kuk#@LW)mtwYy5%`ZIB7mLm+`X*4I@FdaGeup3=v`wVA)geeM+KF!~@IU*#JGnY-wG-c76ph`=wR0LV zN;czGd|SRlQnS+4=)V52+=%e8fq5hi@Q44CyZx-3rC6i-?L^E1niDZ!`_Hz|x)LXz ztix+?f2zZu0oPCHu$rBH@!!?wIj?Yv8Z@Rbhi^(;8MW|RySai`#=k87MP{uZqBzO% zmBxhPdyPsiFAz%NTwGf(e;|WvtLR?<#i@9Km$gi!1U*24|hSSCT#N(%seD--1nNaj_Cx_{2CyU8Gl&4~4vT63u>Xb1` z{`c8?x$r-8Hmq_P;ph;cl5b9g61STar`K>d7E0W1j?g0ot~li{>G)~O+iEmn~$u5KHzB9<%$qj`%==SZt+%U5Yq z+xV(?nf{H>^e=I;{*|Ase`V_5N&A+D&|(n|I-8(U9+ANW<*_d^`D0?U{zklz3W8 zDkrgjc0Fyd*D{ z)!EA6^a(08CpP}ywsV0VS&(Ov)bPEk9l=$G1L7xW`#A6yV>1P9ALfoyi{k~{m@B=P z%MD2@z0y5ouHQp)p+ybSs0kqGn-H5UoNMk$IBOBTMV zC$Yj&=AMYgHQYm}pKC&@F;^L>_Gepu!D@ZCRXHZ!uqB?}gjHnTTw!Xw_RJ@YHh+`4 z5bJ#%Z#l8=4PnTsXhM(WO&(mfvd8DMZM6-J8L^74Gnv9JQIJ^=%{qyRcwkMINInoXPl(@OBa8Mr+ejRRS~3+|`#*2a3@HVFtsIAX1_Qt?Z53(c|@o#`v`E06N-KlYfb0uVA=PXP}A%t|D4{uAyz$zznn7VpRGkRoCKe-5Po%q z0pybg!Z*!Zb`4D=3;+BU)hPlrI&nxS`VGwGQNz6G6wVb-vL!7Q05MxGmbNYGQ^Y1s z!Vh7`Uq*9)!KP&60K{-+t1A& zCPOb_=$JJcE<#^ZY@-~r&S%M-A!8Gc4O68b;ze`bOxNbCneQajbpkfc!Mv=ulQjk8 zB1sDcfORrp{`?S5*G9{DG*He_+r!Ml&lf)>5Rr?nwXfsr(92H7pW{Vl2jm6OLBeGE zzks|*`L6#Z$IlrsL}rf+EYO~xc-@trj)9L~?gUB0pn`!;kSzjayyyQn-QZTYIOzrn zu=#1AmFhyiU9PXuS^SaT4%s;Wihmu!O~|)Z$Jn9;(UUqd=&_~}zkvE|!C+J0Dv$eO zvS_}_>8M`h@j$aGD~`LtRjw}{@*VbaIr1K_lI_yrOqW!kE;*532R7-O$UAQEy-@Lc zp&;i+{yNY^nd^HeM2f>DYwp?m(SIL#&DWIG-^Zy$B%`Yf=u8ybA6sDiv)l=8_KN8V zy?WgVvYk2Z`L>08>ph%j1}fW~_;R2^(ij!cg=Uk;%fDJ@D9`uEn;AUj6~E1|6L~&R zM>jm*ZpZhUv-FCx&^zmn);+BoEbI94fa7bBKQ&$lSkM|(MmMOs$q8<9iaA$cwOh<# z-FF0rxWVPFk1Wufn4_uUyODu~u5Y)eD$ImAk=?1T*#dPf6xkUH9(RlP=$A~XzCF&; z=ii9T{Mj2%vo^88^^wr^0H<46fV{%@^n~_RKu_q?Ixo1+E8a-w0E-hm;`m5uwBPl; znL(4iPP`F-G-lAGlhjZ}j(@FCY@S09R&bYBtY6o6$n_MluL%w>~_n!0O;O5@X?CZbpR^4#uO1u&6|1V0F6kkanNMWEd zK){g^&7okkTU@71uf-d@;7Z45n=q+6{Oeqh6Y?Xxcqa(vMYe%f^a~%kz(Pk=K)(*t zS5Mv8rC+Aacg%V5`{M`y?x(Y^|F&+F2YMgxLMn&&m~IdWrvkchSb3(@4am7s00}la z1j_lS2xJnaUg@&SIbL_UE1FQjKuF8OTiG0nI>TH)Dd4=oTpfQD>~xD0{DypMLcRuf z@t~Ps-Td0;&i|Ee)CUn+fKgG~1=QveWJ4c9K|CEDF6vV;J$5p>?mFEMK2!s*x zT^UOE0VkIV=mSTK*glk}`cObeL&4UN`q0WuhJ20g;t{=ae=`4wu3<# zHbDxGl}tbGxD=b{&ozhXc;C$AACUxMg#KaE1dghYV$s zXi#VgwWde|G}zz-*MgAhmPmuNUUiNyAw=T*a7Y8nvnWU;jta6#gQsA3 zHkS|zz$IRs9C>7a^_|P6a$}^lb_ipGyS?Hg{K6Gn-+E{1Q%{^zcKoR=wcHrmj*B#uS=BH~ zBPI-aBEa^GaTXKGbjT@gbm$K}%D2l%jub~oNe;eBaRl23FZ!7&uAkB)o|@mTUx-=~ z;}aihyy)kB{`7q#F*F45B1NEJ1C6Q-?qE6+geGAVuo)P{Au$gqDC%jDw?5?fUxHak zA}v578M%`Z8kzzigH%=lkb!4z^O%z2Hhy9B;t5N>d-0dnRqy*gxf9lqKEW~a7(OLn z(i1+GJf%}Dvf0#9(YksxHq`)oeeC*Hh$kS9>-gC9 z;jk5F=i4J5(zI2{_u}!(99SX@Vg>1K?g*e&QOjNua(b*DLD?HB=lQk>O2~rtzM(LjEx7&rlTx_4D|phOP}QV;U8 z9!#P&fq8)!S?jc{ZZ9=cc+*;`;FTRnvv|o<3?| zkT481@_=-_4Uoj8@5Pssq7>AHhgroGWQI2hv3N0q$7@w&zS;+_!r{H(POsSflEe)? z#OFz@L5w#BS~ZeeoR)Qv#xPM*D6*S&uB1h)v_bzzLXmccfq;a8u29z(zcOau5943@ z{#$8X{&_>N8QK?qN+xA!zr%|@ZrF=d`RJ2|2ZVx~k&pn&E8gM-Hz*M`3G{QHw_L$+ zjVnEXHNgNba)fT7!GQ4MYy(kxJ*DhVIKhO6+7V2kzdMU}Tr_^zH%Bkq%Z<3S!E~6> zemV2je(mw- z${)o2;>TIiIjuKmq%#d84vu)moEy;LsN>C6I(uT@yXohZj*nwBQ@j^Ot}=Kp)78a$ zSz6_INZ0qe>s#e4x#!7WPkZ@C{op59MtosJktoNCBI$=lX$D1J5eF(pjc;*^_k|)` znb*r8aSPO3GLp&zCN8pBN1cJYA!Zz-F8*h5_f2#r&j%fae4I>lf1m?qK>FWD1NXTt z>qMbbEViQ+6Zmo?)E(aq8Ey8W_Xp;o3EC>*#YhRmi_sCKa)}Ke4q-jU8^QR^pGxJu0@C;%jw`brW2k9;7g}XAmyZyFnq$iuz~@(O0mMZu?V;d~Q1MIp^=)wt^9VT4 z)%5!Kt&=ZpyNrbzH?j^OT_F1`vc`=!pn7i&1&<+j;Dc^4c!Q$xia_q$of;h$86yR< z@EG3CFgHRq?g-Qh-GT7J6iY4eblB9pOyiYeMJ$^0<>eSQA@qAx0MlHjIv;Eg6~C)r z-=Ey)!f*Z81HYVIJ%$@;$VL;zOn8-gE-(nxECd9+8WRXr{HnTN+#r zo}So0ym{{72X%v1f%q}bgDq4c?q>^NHl_=3u3})j+bw>@l@=f#$&|v9I{6GvzBz>L zfWQ^?-+|3&oDd*&hm0x2i4lzq`caf1E2-uhEvv1MdAbrh<~`IQoL^ueatr14uu(cX zY;#nG<&9<}iL%f0^$S3N62F67IKR;hco;{>+$|b^In_0*_esc@IZ-X}qO^peD|87u zMN>z=Flv%4ekrn$9n|aij#`$A;>JmmBQ-X$D0FXWUO?MQEa~281Hk#XSGbMV2s`NmJ z0A&rhpy>z*hjC7MzPkenJUK=W;WRY$%#FVTR3$YaQQSh38sfp?*7QBt<`wVbSH{PZ zf-C=c*;iKv@wlu*9A-q0>aqH7O5`B3MVYcp(Q3O~Nb~_;nUDbF_X3MTzHOFq02mmx z9?&%HV$nj~h%J_c-ZVzQ^~Fc$H(ip8x+9@u{Y6MSaTqJ@gbh~O9Wr(hBi}F4W1KaP zTtpoCht^ToWfC$170_g-@k(H`U;!Q?(TvF6*Xg|Y)>(U(HO{#8MQ&UlHgo;^xM}bb zX?El#YI5*UV1Pwl$7cXjM4{4@Aaq(oM(7wOu-WLY!FA}PDn;AG#Udeq&SbR7MG^v` z2-ITgae^S1tp{9V65gPOx zjjBW9NwOBr*wlnLQJ;8ii#X?kknPq&+lDH$RxG%GKJ-O0atR<GE$ay!PEQT33d|@RtJ`SpRWZ8SxdcQ8`zgz+tnH=psrTOl+MUn<~!=~`yA zhU>$xm;_P3d=dxo3v%H`Fx(G0%P#u)>E9Xs?>~Qy8_aXdXu4cP9jI4SMrRe+XnE& zQ5~(T+j3B)oMdoNnJ#irnGO{%H;$RrA-OBjC=Jc0=-p^qDu4o{eHqJpzrx3YyCv*o z`%ih`tkb_Zbm#zU`{PNqj0p2TrSGjislF#GoJunkz?`Mjpluduak^Tefl{&B_@fNo z%EJVz6{IKtb56y~lR;XeR7mu|_U{lUTVX9aPyRVxti%4m9mTtC;4LBoe@wcPoNySlhjbBHtI17y{+7IV#Ve!coc`=3hDugJ zB~}@doduG`LqQG~M9O!##p1Wd4Tx77Zm~lO2AZvpxfB5+3XU6aK!eixputUsuik+W zV|@YzZXUr@qF4*;eU@s0hLHxMU&L9;aSL|rHD23`S6zI^u;TMBH_8btxfvM3lG6_C zl&8?}!Brt}K?@w~@S@WJ2l7GLM5VDT*%*=`d;~^;>8X^U3LQ5}39kFM2~TmB{rO|{ zx4rk(OGDgbJ7P{W#;k+TDTb4*cZ*+kgTw&UhqNMsv(`uht23#|jO!j9!e~I~L6LS; zA>6Zu{$q{MXJXqx|q6K`#$a2p& zQX&_!kh?{$B$0?-HM9WD;ULl^qP&>Kqz0+mQiBWyrfO<|M@zcQ5BV^sJiI#T%FH0u zpSh+#W~8PvDO)H(njk=pHlqUA4oc7#!)gH-Oct%vsI>0lEqDDcdSlh;_dpP7{nke( zB%E-7cNlbrNuxe7N!tv!LCvGX8*oMtM`^hdn7_g3#f(zofH{UGyxGGJFycUzoFY@B zjHEChl@v0dcPLs1`4y`W1}^;lwBgU4{$&(mxu`Sx2)e7mg^a5nK!QsnY!$uXt#gC^D+wA_pT<*NcnzUt zVv-#U2};+zfUj)<7>N?T7XP|a40l--DsI!_fv?5&wRyg`)24Wu^!Q5spmnM4)*f&p z?{MKFZY2lHJ~3;+oJ*&E+t2|zsFX11AT@UStODEWN=8S_*E1eFNe zRCYLmI%S8`F!oADgrj@h7|2I}N`5Cy1$+9W>}xYdD_B6fI%7;31i-X5Hklk!_7i4* zi$n_+1unI#ffC5N2O8L5-!uw*E%uF-YzPCh9~%?-JvUx&rNS|5BL68AeB0QpSe|H$czy64SrfTk4gi_R@9+_X zu{IR^lX1SZ0h(hUP$^c2HDo4E@8KMtZd0_ zBO)3sO)bTuF+D1tgU3N%Tb3<;1*$@3@ClF+KHnJk`CkBrk!!_Z+d3o%Y*hv2`Gx+H}P z>cEu605DpC{9Q07f@q9Ght^mI&_c9cMMPj|Ye_1t+ejgxGTWAFG6*d00u=+B z0V~D&rfp^Ep2_+^Z=ide&a5691>=-PLnyKj4Z;`=2p@Vc4JF_{H|R5aHw;dEn=*7b z`Enozly0dqs7Uy`093mhe90}wE#1a?X()&vk@X>%>0WhSUO;(#p$Akc;KQn%fPqr9 z89#-Fz&MPG#CRK}B3VHpy98VSHS2_de9K~jSw}qN6*po9=cYiP|JcBd zL1Tk{9)_Y_fP^tGGkeBvx{kk(644HQKAZx)JoaMz5G|gX!1`L=!A-dG5+73%-mZVb%?;T##98Mw?nhqRAu1iN~aX zC{zJHV#a9}zz2-#qL$MnOX|M|G7i4cK9rs_<2NhKFLkPEgqRxZf2>jXIAKO zbH7ufU>*m4NfflEZ2m!(3t%6#BYW|sH%b&(fa5A<3h~lo((iMNU+0%47kA0TUsZfM z|Nd(((2Y31m^KD08Yz~HG(Q#Ktc2|mM77Q>-l(t!(I^Y9RMCy|-!JzAz&w%j(+RWc zgT!g(BF*{#qy68udefXsEa$i0!Y(BRHY{4~;`}HnZe*hg=aO$1UP^famhmG``ey=e$mx7$SM?h+cIDpmck4FrwVao8m0<_T#HwX zb42_fP06l>^yL4W4gZH%%CbTi7yqYu)RvTIPlSLWhaAyDu2!{n_erhoYVF7}Y&lBd zD8QH{R#Y)F0z`muCsH%(hH|Lf!E&+XcZgK1;*^!3rj0&RfCD3ACBSOiWO9gWs%IFM zkbuuCxTy&j5e z=c8e;Ro*r}DlvcYAXh;o_e*FZDzsv1{A7mtTTc@m#G%cg#QgD8q5$rN?K{P|W)Ep$ zLH@&+{C#55c|92YxPuv>ogmp#((Rk5+wD5(= zB_>S!^jPHpNDR+*A6!J<5sHVbC6tO)8`dgb{K?|qZ+Lg| z<@a%8;-X&R3y45yq=u~!v!Xyzjv@I5WFjzE)@LD6VAmuO1$)y

    N+*pAkH~Qyxkg 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

    EQQy)ND2 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≫z$xc#7UDdGsuxk;fG$3vZEN>NY6t11?;iTks>*n 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 k`=tHmAhd0!}GD4cr#14 +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Requires-Dist: colorama; platform_system == 'Windows' +Requires-Dist: importlib-metadata; python_version < '3.8' +Project-URL: Changes, https://click.palletsprojects.com/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 + diff --git a/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD new file mode 100644 index 0000000..e38eddf --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD @@ -0,0 +1,38 @@ +click-8.1.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.8.dist-info/LICENSE.txt,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.8.dist-info/METADATA,sha256=WJtQ6uGS2ybLfvUE4vC0XIhIBr4yFGwjrMBR2fiCQ-Q,2263 +click-8.1.8.dist-info/RECORD,, +click-8.1.8.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +click/__init__.py,sha256=j1DJeCbga4ribkv5uyvIAzI0oFN13fW9mevDKShFelo,3188 +click/__pycache__/__init__.cpython-311.pyc,, +click/__pycache__/_compat.cpython-311.pyc,, +click/__pycache__/_termui_impl.cpython-311.pyc,, +click/__pycache__/_textwrap.cpython-311.pyc,, +click/__pycache__/_winconsole.cpython-311.pyc,, +click/__pycache__/core.cpython-311.pyc,, +click/__pycache__/decorators.cpython-311.pyc,, +click/__pycache__/exceptions.cpython-311.pyc,, +click/__pycache__/formatting.cpython-311.pyc,, +click/__pycache__/globals.cpython-311.pyc,, +click/__pycache__/parser.cpython-311.pyc,, +click/__pycache__/shell_completion.cpython-311.pyc,, +click/__pycache__/termui.cpython-311.pyc,, +click/__pycache__/testing.cpython-311.pyc,, +click/__pycache__/types.cpython-311.pyc,, +click/__pycache__/utils.cpython-311.pyc,, +click/_compat.py,sha256=IGKh_J5QdfKELitnRfTGHneejWxoCw_NX9tfMbdcg3w,18730 +click/_termui_impl.py,sha256=a5z7I9gOFeMmu7Gb6_RPyQ8GPuVP1EeblixcWSPSQPk,24783 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=Q1nEVdctZwvIPOlt4vfHko0TYnHCeE40UEEul8Wpyvs,114748 +click/decorators.py,sha256=7t6F-QWowtLh6F_6l-4YV4Y4yNTcqFQEu9i37zIz68s,18925 +click/exceptions.py,sha256=V7zDT6emqJ8iNl0kF1P5kpFmLMWQ1T1L7aNNKM4YR0w,9600 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=cuJ6Bbo073lgEEmhjr394PeM-QFmXM-Ci-wmfsd7H5g,1954 +click/parser.py,sha256=h4sndcpF5OHrZQN8vD8IWb5OByvW7ABbhRToxovrqS8,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=TR0dXEGcvWb9Eo3aaQEXGhnvNS3FF4H4QcuLnvAvYo4,18636 +click/termui.py,sha256=dLxiS70UOvIYBda_nEEZaPAFOVDVmRs1sEPMuLDowQo,28310 +click/testing.py,sha256=3RA8anCf7TZ8-5RAF5it2Te-aWXBAL5VLasQnMiC2ZQ,16282 +click/types.py,sha256=BD5Qqq4h-8kawBmOIzJlmq4xzThAf4wCvaOLZSBDNx0,36422 +click/utils.py,sha256=ce-IrO9ilII76LGkU354pOdHbepM8UftfNH7SfMU_28,20330 diff --git a/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.11/site-packages/click/__init__.py b/venv/lib/python3.11/site-packages/click/__init__.py new file mode 100644 index 0000000..2610d0e --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/__init__.py @@ -0,0 +1,75 @@ +""" +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 .core import Argument as Argument +from .core import BaseCommand as BaseCommand +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 MultiCommand as MultiCommand +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 HelpOption as HelpOption +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 .parser import OptionParser as OptionParser +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 + +__version__ = "8.1.8" diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bcba0ac7544d9e7f9cc06a1765e715d7664130b7 GIT binary patch literal 3726 zcma)-OH&(3630uR7m^TQjNh2XVBSbPZNL}|0&K=MFa|Dln2x4Z7Cr7)RJUN5(|(Kn z2pjt)_A~UcL#K_{h>h6TizDVXr_D_9aD{YO$oT75sjAG%tWx*iy1R1>{(kxQe`{fZ zv47#<=C9)#{ut|I?60iKIIAYA9d^R$;2jC%PT)@7Nt^^u@+5HzIK@-MY2Y+Z6K8-k zJVTrX&hjjA7jPHvBF+Klc#b%4=bZvC5Ep>Ec{g!4aFG{@i@-g+hqwp0m-iC)0{8Jg z;y&Pe{2uW=;C|ju+z))8-zUBgJirHt2Y?^&2gDD6AM%I95A8?JWB!=<5%3fKg!nP= zQ~s3r3Gg%ijQA<=ARi=t2K<~qCmsYI;zPvGfi+?n7L#H044GsUNfUjk3_Y2q>989qZi4m`_ei6?+dyhJ<+T;^rsDd0Ii zM?4KY&*zC}fEV}z@htEnUnDL8FYzVfGVn5ACZ4ljIj{L^;(6c|zCyeJyvkRJ7lGIK z8u1eF8~%oP8F-zq6Tbp}%ij{e2HxNs#4Es?e3N(;_#J;oyav3*w}{^WZ}V;9b>IrG z5WfZ9;XA||_O7$X_lP%v-}Cpx?|?t>55!x*`+T2x8~7*w6LAIjBmW4z!#`DbkJ;qj z?~Po=w#;vu6=;SQSdMQC?dU2z_gu~Ks&yDyZs1!|RJF4!Ej$-m5LRvLO!NHEH)J5R z(9;~_o5)>CE4192W_pfexK+)zT$pT1%MSzXYuznrr><>%6PgE6B;I{^x}n(fx3^aGf!f< zz1v3hrf;W#Q4`=Rg0H!k8&3f|KNel2%e4EODQ*hu+Our2Do`?Nvwzcb08oqvAUVlx5x>=VJ4p+acy3h;;SpqtWlxYhC8wKY; z&Bt1VdG6^KmI3Xo(X6DXT3C4of|}whoHb{_(DCVh z1Q-#g2H};BQ!{n<29w)|ho8WeuAF<8iC<=Sj8L3d4ssHE1fQwBPlsD40J%NeGr}*1 zOKtDmKR{=8-@SD;Z`#R~Ps@*t5cilqKKZhL@E!x5)ZupwkUu>*`f^y=JwD#ufnoCW zbe}%2x7zcSI;($${4U&FT!Ae$d|$6x*s(qwo>{ITuk;|4!f?RZgHAkxJ6D(I3zy>j zo?0o*msSoYKQ}VEUiC~}ZzSQa3JI@eCX*;Blr%~PC5zI9f^T=32WjMPFL)r~P0wUE zN)e?8r5B|Sce8EU{Vw z#cA!vtB5Jq?gTd@rdYeKww`ip?X7hwmj~`ryEARQnXS26yYc_5YK_yn=b?xx7PFB^ zwV1*0OR-p80uf?19H|zw=}5Jh4MwW9i#!=I#oFa+-C=9?*@!9DE{;+-Rk0i~#bPxG f#EjW$q*|;lfe5i$0#x+R;=o_>_%DBk=h*)M2zW=^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/_compat.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/_compat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86cda57a02d90dd7b81ae7d0554d07ed1337e2fc GIT binary patch literal 28668 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/_termui_impl.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/_termui_impl.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f2cc7f821d51d3baa5d53a1790aca3bdea8d50d GIT binary patch literal 33269 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 U2xh3Wvm9GNq#F+DJ{)FsD^!k)38KM57Oo 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 T{nkN-{DQF!I@n)SF#!J?&X{ql literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..deabf4f235559ab5bb535c915e6d08b745cc321a GIT binary patch literal 142557 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%0A{@k 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/exceptions.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/exceptions.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..984b1f650fb663d822d02dd512b419ca01355343 GIT binary patch literal 16346 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/formatting.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/formatting.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99914a60bf44fc1391974bee4bee912ce165e808 GIT binary patch literal 15683 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 K+5aRmKmH5ia5U2Z literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/parser.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2ef720a1864c35a4d1cf76e01734dcadc18168f GIT binary patch literal 23127 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 Ky+JD5;r|C_@RI@n literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/shell_completion.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/shell_completion.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0da0ce6b07fb7ce4ff94aca5e5ca3c2370d549a2 GIT binary patch literal 24123 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 UQ>LOZThW}WXr8sxA5$s+AAy#W`~Uy| literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef3441e3461113360ba3a1cd699e96eeb9b993eb GIT binary patch literal 28034 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 HM4SH$XK{}7 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/_compat.py b/venv/lib/python3.11/site-packages/click/_compat.py new file mode 100644 index 0000000..9153d15 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_compat.py @@ -0,0 +1,623 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +WIN = sys.platform.startswith("win") +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO[t.Any]) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, "os.PathLike[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/venv/lib/python3.11/site-packages/click/_termui_impl.py b/venv/lib/python3.11/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..ad9f8f6 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_termui_impl.py @@ -0,0 +1,788 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" + +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ +from io import StringIO +from shutil import which +from types import TracebackType + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + if _tempfilepager(generator, pager_cmd, color): + return + elif _pipepager(generator, pager_cmd, color): + return + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if (WIN or sys.platform.startswith("os2")) and _tempfilepager( + generator, "more", color + ): + return + if _pipepager(generator, "less", color): + return + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if _pipepager(generator, "more", color): + return + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> bool: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + + Returns True if the command was found, False otherwise and thus another + pager should be attempted. + """ + cmd_absolute = which(cmd) + if cmd_absolute is None: + return False + + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen( + [cmd_absolute], + shell=True, + stdin=subprocess.PIPE, + env=env, + errors="replace", + text=True, + ) + assert c.stdin is not None + try: + for text in generator: + if not color: + text = strip_ansi(text) + + c.stdin.write(text) + except (OSError, KeyboardInterrupt): + pass + else: + c.stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + return True + + +def _tempfilepager( + generator: t.Iterable[str], + cmd: str, + color: t.Optional[bool], +) -> bool: + """Page through text by invoking a program on a temporary file. + + Returns True if the command was found, False otherwise and thus another + pager should be attempted. + """ + # Which is necessary for Windows, it is also recommended in the Popen docs. + cmd_absolute = which(cmd) + if cmd_absolute is None: + return False + + import subprocess + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + subprocess.call([cmd_absolute, filename]) + except OSError: + # Command not found + pass + finally: + os.close(fd) + os.unlink(filename) + + return True + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if which(editor) is not None: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url) + args = ["explorer", f"/select,{url}"] + else: + args = ["start"] + if wait: + args.append("/WAIT") + args.append("") + args.append(url) + try: + return subprocess.call(args) + except OSError: + # Command not found + return 127 + elif CYGWIN: + if locate: + url = _unquote_file(url) + args = ["cygstart", os.path.dirname(url)] + else: + args = ["cygstart"] + if wait: + args.append("-w") + args.append(url) + try: + return subprocess.call(args) + except OSError: + # Command not found + return 127 + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import termios + import tty + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/venv/lib/python3.11/site-packages/click/_textwrap.py b/venv/lib/python3.11/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/venv/lib/python3.11/site-packages/click/_winconsole.py b/venv/lib/python3.11/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/venv/lib/python3.11/site-packages/click/core.py b/venv/lib/python3.11/site-packages/click/core.py new file mode 100644 index 0000000..e630501 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/core.py @@ -0,0 +1,3047 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .decorators import HelpOption + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Returns all declared parameters in the order they should be processed. + + The declared parameters are re-shuffled depending on the order in which + they were invoked, as well as the eagerness of each parameters. + + The invocation order takes precedence over the declaration order. I.e. the + order in which the user provided them to the CLI is respected. + + This behavior and its effect on callback evaluation is detailed at: + https://click.palletsprojects.com/en/stable/advanced/#callback-evaluation-order + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[t.Callable[[str], str]] = ( + token_normalize_func + ) + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional[Context] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + @t.overload + def invoke( + __self, + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: ... + + @t.overload + def invoke( + __self, + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: ... + + def invoke( + __self, + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward(__self, __cmd: "Command", *args: t.Any, **kwargs: t.Any) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.MutableMapping[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, # type: ignore[arg-type] + info_name=info_name, + parent=parent, + **extra, + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invocable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List[CompletionItem] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt) as e: + echo(file=sys.stderr) + raise Abort() from e + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List[Parameter] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self._help_option: t.Optional[HelpOption] = None + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object. + + Unless ``add_help_option`` is ``False``. + + .. versionchanged:: 8.1.8 + The help option is now cached to avoid creating it multiple times. + """ + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + # Cache the help option object in private _help_option attribute to + # avoid creating it multiple times. Not doing this will break the + # callback odering by iter_params_for_processing(), which relies on + # object comparison. + if self._help_option is None: + # Avoid circular import. + from .decorators import HelpOption + + self._help_option = HelpOption(help_options) + + return self._help_option + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List[CompletionItem] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv # type: ignore[return-value] + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.MutableMapping[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The latter is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator[t.Any]: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError( + f"Could not determine name for option with declarations {decls!r}" + ) + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if default_value else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + elif default_value == "": + default_string = '""' + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return t.cast(Option, param).flag_value + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the constructor of :class:`Parameter`. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Argument is marked as exposed, but does not have a name.") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/venv/lib/python3.11/site-packages/click/decorators.py b/venv/lib/python3.11/site-packages/click/decorators.py new file mode 100644 index 0000000..bcf8906 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/decorators.py @@ -0,0 +1,562 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + return decorator + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + message % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +class HelpOption(Option): + """Pre-configured ``--help`` option which immediately prints the help page + and exits the program. + """ + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + **kwargs: t.Any, + ) -> None: + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs.setdefault("callback", self.show_help) + + super().__init__(param_decls, **kwargs) + + @staticmethod + def show_help(ctx: Context, param: Parameter, value: bool) -> None: + """Callback that print the help page on ```` and exits.""" + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Decorator for the pre-configured ``--help`` option defined above. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + kwargs.setdefault("cls", HelpOption) + return option(*param_decls, **kwargs) diff --git a/venv/lib/python3.11/site-packages/click/exceptions.py b/venv/lib/python3.11/site-packages/click/exceptions.py new file mode 100644 index 0000000..0b83151 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/exceptions.py @@ -0,0 +1,296 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .globals import resolve_color_default +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]], +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + # The context will be removed by the time we print the message, so cache + # the color settings here to be used later on (in `show`) + self.show_color: t.Optional[bool] = resolve_color_default() + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=self.show_color, + ) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd: t.Optional[Command] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename: str = format_filename(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code: int = code diff --git a/venv/lib/python3.11/site-packages/click/formatting.py b/venv/lib/python3.11/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/venv/lib/python3.11/site-packages/click/globals.py b/venv/lib/python3.11/site-packages/click/globals.py new file mode 100644 index 0000000..191e712 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/globals.py @@ -0,0 +1,67 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/venv/lib/python3.11/site-packages/click/parser.py b/venv/lib/python3.11/site-packages/click/parser.py new file mode 100644 index 0000000..600b843 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/parser.py @@ -0,0 +1,531 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" + +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes: t.Set[str] = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: t.Any, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List[CoreParameter] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args: bool = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options: bool = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we recombine the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/venv/lib/python3.11/site-packages/click/py.typed b/venv/lib/python3.11/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/click/shell_completion.py b/venv/lib/python3.11/site-packages/click/shell_completion.py new file mode 100644 index 0000000..07d0f09 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/shell_completion.py @@ -0,0 +1,603 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + @staticmethod + def _check_version() -> None: + import shutil + import subprocess + + bash_exe = shutil.which("bash") + + if bash_exe is None: + match = None + else: + output = subprocess.run( + [bash_exe, "--norc", "-c", 'echo "${BASH_VERSION}"'], + stdout=subprocess.PIPE, + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + return cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + # Will be None if expose_value is False. + value = ctx.params.get(param.name) + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + sub_ctx = ctx + + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/venv/lib/python3.11/site-packages/click/termui.py b/venv/lib/python3.11/site-packages/click/termui.py new file mode 100644 index 0000000..c084f19 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/venv/lib/python3.11/site-packages/click/testing.py b/venv/lib/python3.11/site-packages/click/testing.py new file mode 100644 index 0000000..772b215 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/testing.py @@ -0,0 +1,483 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import _compat +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(input) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env: t.Mapping[str, t.Optional[str]] = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + old__compat_should_strip_ansi = _compat.should_strip_ansi + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + _compat.should_strip_ansi = should_strip_ansi + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + _compat.should_strip_ansi = old__compat_should_strip_ansi + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: + pass diff --git a/venv/lib/python3.11/site-packages/click/types.py b/venv/lib/python3.11/site-packages/click/types.py new file mode 100644 index 0000000..a70fd58 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/types.py @@ -0,0 +1,1093 @@ +import os +import stat +import sys +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import format_filename +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name: str = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = sys.getfilesystemencoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type[t.Any]] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Files can also be opened atomically in which case all writes go into a + separate file in the same folder and upon completion the file will + be moved over to the original location. This is useful if a file + regularly read by other users is modified. + + See :ref:`file-args` for more information. + + .. versionchanged:: 2.0 + Added the ``atomic`` parameter. + """ + + name = "filename" + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name: str = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} {filename!r} is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/venv/lib/python3.11/site-packages/click/utils.py b/venv/lib/python3.11/site-packages/click/utils.py new file mode 100644 index 0000000..836c6f2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO[t.Any]: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file, color) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO[t.Any]: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name or Path of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict"``. This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return filename + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no effect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO[t.Any]) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/venv/lib/python3.11/site-packages/distutils-precedence.pth b/venv/lib/python3.11/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..7f009fe --- /dev/null +++ b/venv/lib/python3.11/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'local') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/METADATA b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/METADATA new file mode 100644 index 0000000..0d84502 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/METADATA @@ -0,0 +1,565 @@ +Metadata-Version: 2.1 +Name: fastapi +Version: 0.115.12 +Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production +Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= +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: Environment :: Web Environment +Classifier: Framework :: AsyncIO +Classifier: Framework :: FastAPI +Classifier: Framework :: Pydantic +Classifier: Framework :: Pydantic :: 1 +Classifier: Framework :: Pydantic :: 2 +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +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: Topic :: Internet :: WWW/HTTP :: HTTP Servers +Classifier: Topic :: Internet :: WWW/HTTP +Project-URL: Homepage, https://github.com/fastapi/fastapi +Project-URL: Documentation, https://fastapi.tiangolo.com/ +Project-URL: Repository, https://github.com/fastapi/fastapi +Project-URL: Issues, https://github.com/fastapi/fastapi/issues +Project-URL: Changelog, https://fastapi.tiangolo.com/release-notes/ +Requires-Python: >=3.8 +Requires-Dist: starlette<0.47.0,>=0.40.0 +Requires-Dist: pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4 +Requires-Dist: typing-extensions>=4.8.0 +Provides-Extra: standard +Requires-Dist: fastapi-cli[standard]>=0.0.5; extra == "standard" +Requires-Dist: httpx>=0.23.0; extra == "standard" +Requires-Dist: jinja2>=3.1.5; extra == "standard" +Requires-Dist: python-multipart>=0.0.18; extra == "standard" +Requires-Dist: email-validator>=2.0.0; extra == "standard" +Requires-Dist: uvicorn[standard]>=0.12.0; extra == "standard" +Provides-Extra: all +Requires-Dist: fastapi-cli[standard]>=0.0.5; extra == "all" +Requires-Dist: httpx>=0.23.0; extra == "all" +Requires-Dist: jinja2>=3.1.5; extra == "all" +Requires-Dist: python-multipart>=0.0.18; extra == "all" +Requires-Dist: itsdangerous>=1.1.0; extra == "all" +Requires-Dist: pyyaml>=5.3.1; extra == "all" +Requires-Dist: ujson!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,>=4.0.1; extra == "all" +Requires-Dist: orjson>=3.2.1; extra == "all" +Requires-Dist: email-validator>=2.0.0; extra == "all" +Requires-Dist: uvicorn[standard]>=0.12.0; extra == "all" +Requires-Dist: pydantic-settings>=2.0.0; extra == "all" +Requires-Dist: pydantic-extra-types>=2.0.0; extra == "all" +Description-Content-Type: text/markdown + +

    + FastAPI +

    +

    + FastAPI framework, high performance, easy to learn, fast to code, ready for production +

    +

    + + Test + + + Coverage + + + Package version + + + Supported Python versions + +

    + +--- + +**Documentation**: https://fastapi.tiangolo.com + +**Source Code**: https://github.com/fastapi/fastapi + +--- + +FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints. + +The key features are: + +* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance). +* **Fast to code**: Increase the speed to develop features by about 200% to 300%. * +* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. * +* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. +* **Easy**: Designed to be easy to use and learn. Less time reading docs. +* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs. +* **Robust**: Get production-ready code. With automatic interactive documentation. +* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema. + +* estimation based on tests on an internal development team, building production applications. + +## Sponsors + + + + + + + + + + + + + + + + + + + + + + + + +Other sponsors + +## Opinions + +"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" + +
    Kabir Khan - Microsoft (ref)
    + +--- + +"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" + +
    Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)
    + +--- + +"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" + +
    Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)
    + +--- + +"_I’m over the moon excited about **FastAPI**. It’s so fun!_" + +
    Brian Okken - Python Bytes podcast host (ref)
    + +--- + +"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._" + +
    Timothy Crosley - Hug creator (ref)
    + +--- + +"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_" + +"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_" + +
    Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators (ref) - (ref)
    + +--- + +"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._" + +
    Deon Pillsbury - Cisco (ref)
    + +--- + +## **Typer**, the FastAPI of CLIs + + + +If you are building a CLI app to be used in the terminal instead of a web API, check out **Typer**. + +**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀 + +## Requirements + +FastAPI stands on the shoulders of giants: + +* Starlette for the web parts. +* Pydantic for the data parts. + +## Installation + +Create and activate a virtual environment and then install FastAPI: + +
    + +```console +$ pip install "fastapi[standard]" + +---> 100% +``` + +
    + +**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals. + +## Example + +### Create it + +* Create a file `main.py` with: + +```Python +from typing import Union + +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} +``` + +
    +Or use async def... + +If your code uses `async` / `await`, use `async def`: + +```Python hl_lines="9 14" +from typing import Union + +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +async def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +async def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} +``` + +**Note**: + +If you don't know, check the _"In a hurry?"_ section about `async` and `await` in the docs. + +
    + +### Run it + +Run the server with: + +
    + +```console +$ fastapi dev main.py + + ╭────────── FastAPI CLI - Development mode ───────────╮ + │ │ + │ Serving at: http://127.0.0.1:8000 │ + │ │ + │ API docs: http://127.0.0.1:8000/docs │ + │ │ + │ Running in development mode, for production use: │ + │ │ + │ fastapi run │ + │ │ + ╰─────────────────────────────────────────────────────╯ + +INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] +INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) +INFO: Started reloader process [2248755] using WatchFiles +INFO: Started server process [2248757] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +
    + +
    +About the command fastapi dev main.py... + +The command `fastapi dev` reads your `main.py` file, detects the **FastAPI** app in it, and starts a server using Uvicorn. + +By default, `fastapi dev` will start with auto-reload enabled for local development. + +You can read more about it in the FastAPI CLI docs. + +
    + +### Check it + +Open your browser at http://127.0.0.1:8000/items/5?q=somequery. + +You will see the JSON response as: + +```JSON +{"item_id": 5, "q": "somequery"} +``` + +You already created an API that: + +* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`. +* Both _paths_ take `GET` operations (also known as HTTP _methods_). +* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`. +* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`. + +### Interactive API docs + +Now go to http://127.0.0.1:8000/docs. + +You will see the automatic interactive API documentation (provided by Swagger UI): + +![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png) + +### Alternative API docs + +And now, go to http://127.0.0.1:8000/redoc. + +You will see the alternative automatic documentation (provided by ReDoc): + +![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png) + +## Example upgrade + +Now modify the file `main.py` to receive a body from a `PUT` request. + +Declare the body using standard Python types, thanks to Pydantic. + +```Python hl_lines="4 9-12 25-27" +from typing import Union + +from fastapi import FastAPI +from pydantic import BaseModel + +app = FastAPI() + + +class Item(BaseModel): + name: str + price: float + is_offer: Union[bool, None] = None + + +@app.get("/") +def read_root(): + return {"Hello": "World"} + + +@app.get("/items/{item_id}") +def read_item(item_id: int, q: Union[str, None] = None): + return {"item_id": item_id, "q": q} + + +@app.put("/items/{item_id}") +def update_item(item_id: int, item: Item): + return {"item_name": item.name, "item_id": item_id} +``` + +The `fastapi dev` server should reload automatically. + +### Interactive API docs upgrade + +Now go to http://127.0.0.1:8000/docs. + +* The interactive API documentation will be automatically updated, including the new body: + +![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) + +* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API: + +![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png) + +* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen: + +![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png) + +### Alternative API docs upgrade + +And now, go to http://127.0.0.1:8000/redoc. + +* The alternative documentation will also reflect the new query parameter and body: + +![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) + +### Recap + +In summary, you declare **once** the types of parameters, body, etc. as function parameters. + +You do that with standard modern Python types. + +You don't have to learn a new syntax, the methods or classes of a specific library, etc. + +Just standard **Python**. + +For example, for an `int`: + +```Python +item_id: int +``` + +or for a more complex `Item` model: + +```Python +item: Item +``` + +...and with that single declaration you get: + +* Editor support, including: + * Completion. + * Type checks. +* Validation of data: + * Automatic and clear errors when the data is invalid. + * Validation even for deeply nested JSON objects. +* Conversion of input data: coming from the network to Python data and types. Reading from: + * JSON. + * Path parameters. + * Query parameters. + * Cookies. + * Headers. + * Forms. + * Files. +* Conversion of output data: converting from Python data and types to network data (as JSON): + * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc). + * `datetime` objects. + * `UUID` objects. + * Database models. + * ...and many more. +* Automatic interactive API documentation, including 2 alternative user interfaces: + * Swagger UI. + * ReDoc. + +--- + +Coming back to the previous code example, **FastAPI** will: + +* Validate that there is an `item_id` in the path for `GET` and `PUT` requests. +* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests. + * If it is not, the client will see a useful, clear error. +* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests. + * As the `q` parameter is declared with `= None`, it is optional. + * Without the `None` it would be required (as is the body in the case with `PUT`). +* For `PUT` requests to `/items/{item_id}`, read the body as JSON: + * Check that it has a required attribute `name` that should be a `str`. + * Check that it has a required attribute `price` that has to be a `float`. + * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present. + * All this would also work for deeply nested JSON objects. +* Convert from and to JSON automatically. +* Document everything with OpenAPI, that can be used by: + * Interactive documentation systems. + * Automatic client code generation systems, for many languages. +* Provide 2 interactive documentation web interfaces directly. + +--- + +We just scratched the surface, but you already get the idea of how it all works. + +Try changing the line with: + +```Python + return {"item_name": item.name, "item_id": item_id} +``` + +...from: + +```Python + ... "item_name": item.name ... +``` + +...to: + +```Python + ... "item_price": item.price ... +``` + +...and see how your editor will auto-complete the attributes and know their types: + +![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png) + +For a more complete example including more features, see the Tutorial - User Guide. + +**Spoiler alert**: the tutorial - user guide includes: + +* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**. +* How to set **validation constraints** as `maximum_length` or `regex`. +* A very powerful and easy to use **Dependency Injection** system. +* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth. +* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic). +* **GraphQL** integration with Strawberry and other libraries. +* Many extra features (thanks to Starlette) as: + * **WebSockets** + * extremely easy tests based on HTTPX and `pytest` + * **CORS** + * **Cookie Sessions** + * ...and more. + +## Performance + +Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*) + +To understand more about it, see the section Benchmarks. + +## Dependencies + +FastAPI depends on Pydantic and Starlette. + +### `standard` Dependencies + +When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies: + +Used by Pydantic: + +* email-validator - for email validation. + +Used by Starlette: + +* httpx - Required if you want to use the `TestClient`. +* jinja2 - Required if you want to use the default template configuration. +* python-multipart - Required if you want to support form "parsing", with `request.form()`. + +Used by FastAPI / Starlette: + +* uvicorn - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving. +* `fastapi-cli` - to provide the `fastapi` command. + +### Without `standard` Dependencies + +If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`. + +### Additional Optional Dependencies + +There are some additional dependencies you might want to install. + +Additional optional Pydantic dependencies: + +* pydantic-settings - for settings management. +* pydantic-extra-types - for extra types to be used with Pydantic. + +Additional optional FastAPI dependencies: + +* orjson - Required if you want to use `ORJSONResponse`. +* ujson - Required if you want to use `UJSONResponse`. + +## License + +This project is licensed under the terms of the MIT license. diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/RECORD b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/RECORD new file mode 100644 index 0000000..811b1cc --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/RECORD @@ -0,0 +1,97 @@ +../../../bin/fastapi,sha256=GYOVd1mKfhSg9P9vi4fn8KgJr8qYrPBSIdJdAI3syI0,234 +fastapi-0.115.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +fastapi-0.115.12.dist-info/METADATA,sha256=mV7D-DjELmGAedtcxayASLcleQv41h4mqHQhlqtLu1s,27671 +fastapi-0.115.12.dist-info/RECORD,, +fastapi-0.115.12.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi-0.115.12.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90 +fastapi-0.115.12.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61 +fastapi-0.115.12.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086 +fastapi/__init__.py,sha256=sgu-sth5uRYC--mOXSta-IPYjnDKUrpRSz6LuvKHf9o,1082 +fastapi/__main__.py,sha256=bKePXLdO4SsVSM6r9SVoLickJDcR2c0cTOxZRKq26YQ,37 +fastapi/__pycache__/__init__.cpython-311.pyc,, +fastapi/__pycache__/__main__.cpython-311.pyc,, +fastapi/__pycache__/_compat.cpython-311.pyc,, +fastapi/__pycache__/applications.cpython-311.pyc,, +fastapi/__pycache__/background.cpython-311.pyc,, +fastapi/__pycache__/cli.cpython-311.pyc,, +fastapi/__pycache__/concurrency.cpython-311.pyc,, +fastapi/__pycache__/datastructures.cpython-311.pyc,, +fastapi/__pycache__/encoders.cpython-311.pyc,, +fastapi/__pycache__/exception_handlers.cpython-311.pyc,, +fastapi/__pycache__/exceptions.cpython-311.pyc,, +fastapi/__pycache__/logger.cpython-311.pyc,, +fastapi/__pycache__/param_functions.cpython-311.pyc,, +fastapi/__pycache__/params.cpython-311.pyc,, +fastapi/__pycache__/requests.cpython-311.pyc,, +fastapi/__pycache__/responses.cpython-311.pyc,, +fastapi/__pycache__/routing.cpython-311.pyc,, +fastapi/__pycache__/staticfiles.cpython-311.pyc,, +fastapi/__pycache__/templating.cpython-311.pyc,, +fastapi/__pycache__/testclient.cpython-311.pyc,, +fastapi/__pycache__/types.cpython-311.pyc,, +fastapi/__pycache__/utils.cpython-311.pyc,, +fastapi/__pycache__/websockets.cpython-311.pyc,, +fastapi/_compat.py,sha256=Rg7kA7uue4Z6yr8T7hf8b7G6PeC_06mK004Nnykijfk,23953 +fastapi/applications.py,sha256=Ix-o9pQAWhEDf9J0Q1hZ0nBB1uP72c-Y3oiYzvrwqiM,176316 +fastapi/background.py,sha256=rouLirxUANrcYC824MSMypXL_Qb2HYg2YZqaiEqbEKI,1768 +fastapi/cli.py,sha256=OYhZb0NR_deuT5ofyPF2NoNBzZDNOP8Salef2nk-HqA,418 +fastapi/concurrency.py,sha256=MirfowoSpkMQZ8j_g0ZxaQKpV6eB3G-dB5TgcXCrgEA,1424 +fastapi/datastructures.py,sha256=b2PEz77XGq-u3Ur1Inwk0AGjOsQZO49yF9C7IPJ15cY,5766 +fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi/dependencies/__pycache__/__init__.cpython-311.pyc,, +fastapi/dependencies/__pycache__/models.cpython-311.pyc,, +fastapi/dependencies/__pycache__/utils.cpython-311.pyc,, +fastapi/dependencies/models.py,sha256=Pjl6vx-4nZ5Tta9kJa3-RfQKkXtCpS09-FhMgs9eWNs,1507 +fastapi/dependencies/utils.py,sha256=SwOOdQYOC0E4thJ-n1a0ohslWN9duyasNY_JBdWPTsY,35971 +fastapi/encoders.py,sha256=LvwYmFeOz4tVwvgBoC5rvZnbr7hZr73KGrU8O7zSptU,11068 +fastapi/exception_handlers.py,sha256=MBrIOA-ugjJDivIi4rSsUJBdTsjuzN76q4yh0q1COKw,1332 +fastapi/exceptions.py,sha256=taNixuFEXb67lI1bnX1ubq8y8TseJ4yoPlWjyP0fTzk,4969 +fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54 +fastapi/middleware/__init__.py,sha256=oQDxiFVcc1fYJUOIFvphnK7pTT5kktmfL32QXpBFvvo,58 +fastapi/middleware/__pycache__/__init__.cpython-311.pyc,, +fastapi/middleware/__pycache__/cors.cpython-311.pyc,, +fastapi/middleware/__pycache__/gzip.cpython-311.pyc,, +fastapi/middleware/__pycache__/httpsredirect.cpython-311.pyc,, +fastapi/middleware/__pycache__/trustedhost.cpython-311.pyc,, +fastapi/middleware/__pycache__/wsgi.cpython-311.pyc,, +fastapi/middleware/cors.py,sha256=ynwjWQZoc_vbhzZ3_ZXceoaSrslHFHPdoM52rXr0WUU,79 +fastapi/middleware/gzip.py,sha256=xM5PcsH8QlAimZw4VDvcmTnqQamslThsfe3CVN2voa0,79 +fastapi/middleware/httpsredirect.py,sha256=rL8eXMnmLijwVkH7_400zHri1AekfeBd6D6qs8ix950,115 +fastapi/middleware/trustedhost.py,sha256=eE5XGRxGa7c5zPnMJDGp3BxaL25k5iVQlhnv-Pk0Pss,109 +fastapi/middleware/wsgi.py,sha256=Z3Ue-7wni4lUZMvH3G9ek__acgYdJstbnpZX_HQAboY,79 +fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi/openapi/__pycache__/__init__.cpython-311.pyc,, +fastapi/openapi/__pycache__/constants.cpython-311.pyc,, +fastapi/openapi/__pycache__/docs.cpython-311.pyc,, +fastapi/openapi/__pycache__/models.cpython-311.pyc,, +fastapi/openapi/__pycache__/utils.cpython-311.pyc,, +fastapi/openapi/constants.py,sha256=adGzmis1L1HJRTE3kJ5fmHS_Noq6tIY6pWv_SFzoFDU,153 +fastapi/openapi/docs.py,sha256=XcQq-ZbQdC5sI0gIGu5MoHK1q-OFaqws7-ORTo6sjY4,10348 +fastapi/openapi/models.py,sha256=PqkxQiqcEgjKuhfUIWPZPQcyTcubtUCB3vcObLsB7VE,15397 +fastapi/openapi/utils.py,sha256=e00G_p0IdpiffBUaq31BUyiloXbpld8RryKYnYKisdY,23964 +fastapi/param_functions.py,sha256=JHNPLIYvoAwdnZZavIVsxOat8x23fX_Kl33reh7HKl8,64019 +fastapi/params.py,sha256=g450axUBQgQJODdtM7WBxZbQj9Z64inFvadrgHikBbU,28237 +fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142 +fastapi/responses.py,sha256=QNQQlwpKhQoIPZTTWkpc9d_QGeGZ_aVQPaDV3nQ8m7c,1761 +fastapi/routing.py,sha256=qwk_Vm1k4vDGdeEskNCVYTK01fDgYikqfOS_lf0DqAc,176216 +fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881 +fastapi/security/__pycache__/__init__.cpython-311.pyc,, +fastapi/security/__pycache__/api_key.cpython-311.pyc,, +fastapi/security/__pycache__/base.cpython-311.pyc,, +fastapi/security/__pycache__/http.cpython-311.pyc,, +fastapi/security/__pycache__/oauth2.cpython-311.pyc,, +fastapi/security/__pycache__/open_id_connect_url.cpython-311.pyc,, +fastapi/security/__pycache__/utils.cpython-311.pyc,, +fastapi/security/api_key.py,sha256=cBI5Z4zWVjL1uJrsjTeLy7MafHPAO2HQPzTrpyoIYWA,9094 +fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141 +fastapi/security/http.py,sha256=rWR2x-5CUsjWmRucYthwRig6MG1o-boyrr4Xo-PuuxU,13606 +fastapi/security/oauth2.py,sha256=xCo5j1qpze6CvEuJHIneOI0v2fodGVMpHHVnHpiLfoM,21589 +fastapi/security/open_id_connect_url.py,sha256=8vizZ2tGqEp1ur8SwtVgyHJhGAJ5AqahgcvSpaIioDI,2722 +fastapi/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293 +fastapi/staticfiles.py,sha256=iirGIt3sdY2QZXd36ijs3Cj-T0FuGFda3cd90kM9Ikw,69 +fastapi/templating.py,sha256=4zsuTWgcjcEainMJFAlW6-gnslm6AgOS1SiiDWfmQxk,76 +fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66 +fastapi/types.py,sha256=nFb36sK3DSoqoyo7Miwy3meKK5UdFBgkAgLSzQlUVyI,383 +fastapi/utils.py,sha256=y8Bj5ttMaI9tS4D60OUgXqKnktBr99NdYUnHHV9LgoY,7948 +fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222 diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/REQUESTED b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/WHEEL b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/WHEEL new file mode 100644 index 0000000..64b991e --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: pdm-backend (2.4.3) +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/entry_points.txt b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/entry_points.txt new file mode 100644 index 0000000..b81849e --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +fastapi = fastapi.cli:main + +[gui_scripts] + diff --git a/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/licenses/LICENSE b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/licenses/LICENSE new file mode 100644 index 0000000..3e92463 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi-0.115.12.dist-info/licenses/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 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.11/site-packages/fastapi/__init__.py b/venv/lib/python3.11/site-packages/fastapi/__init__.py new file mode 100644 index 0000000..80eb783 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/__init__.py @@ -0,0 +1,25 @@ +"""FastAPI framework, high performance, easy to learn, fast to code, ready for production""" + +__version__ = "0.115.12" + +from starlette import status as status + +from .applications import FastAPI as FastAPI +from .background import BackgroundTasks as BackgroundTasks +from .datastructures import UploadFile as UploadFile +from .exceptions import HTTPException as HTTPException +from .exceptions import WebSocketException as WebSocketException +from .param_functions import Body as Body +from .param_functions import Cookie as Cookie +from .param_functions import Depends as Depends +from .param_functions import File as File +from .param_functions import Form as Form +from .param_functions import Header as Header +from .param_functions import Path as Path +from .param_functions import Query as Query +from .param_functions import Security as Security +from .requests import Request as Request +from .responses import Response as Response +from .routing import APIRouter as APIRouter +from .websockets import WebSocket as WebSocket +from .websockets import WebSocketDisconnect as WebSocketDisconnect diff --git a/venv/lib/python3.11/site-packages/fastapi/__main__.py b/venv/lib/python3.11/site-packages/fastapi/__main__.py new file mode 100644 index 0000000..fc36465 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/__main__.py @@ -0,0 +1,3 @@ +from fastapi.cli import main + +main() diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..032d89abe34031bdfeada4245ca0261058f5452e GIT binary patch literal 1401 zcma)*OK;RV6vsWCN9H~4OkcdS;Zac<%4>nHt}X>CSb$1fK(Y{#o4C_3P8@7!hGBvD z7WX3{zD<_VtSTWPAvQ?tSRjr~sfg%;=&v)sbL?}HbL@H7YSj@u&p&?d-z*{YK|8;m zsRQ`>9pHcDBaHk4F8EV^kxhj~Tr42JlaFx}=25uOx z0XK2eaGkZnHf|ek0C#Z5a1(eMPaAFl&)^xuZQw5M8twr1aL@2G@GPD+JOez3=L~m& z=kdJZ9$N?(@uJ~bb}T%Oj~kw2C&H8Xq~UpXDm;x(8(siDgU4=NLvb`7d_w1O8T`ocrd34#PM2>C6ZAOWRmhD~0(XPjRSQM1_V;eTxvEY8< zsenhXtCv?+SFf+EUiqZQy;PV~q#`Pjp9()+>)^ex(pe+kpf7k5`P)PeB!udZW5$WU z9xw`C>)!VE#@$yQjdf`Vbf40lE$$7d`aN1&{E4Mix1Uk{WLt`5Gx?<^|R%soY z(wpwVS5u)^Hi+7T-}0k`3Y}lwqFy2brP z+DvORqfHmgq$+;)E=5nfHF%lnUy51nTX143i27nqd-W0Bk>*IGn1_H^0P`Mw1&h8t zaE3%UqtVErA%79jA!m@vBWFmXp~He5CmyRk9$key~J_*?a#5bhbH|BCZaU0*2q2JDw&p-{-svlKnsZ!f-W?4xsOUi)Y{%_~DU)4Vct zEzK)KH`2T^^k14+hL+O2GIS};D??72*HKx2Q|He;7gLl|hE~(OGISx$E6b-qg`*-X QDat8BYw1xEXW<-v0ImU_@Bjb+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/__main__.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/__main__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9f09e11e2af85ccd5d2fbbb661cc8c971ae3e61 GIT binary patch literal 269 zcmZ3^%ge<81aZ$^r>g?##~=<2FhLog)qsrY3@HpLj5!Rsj8Tk?3``8EjLU$ct6^#x z7#UKSf*CZKUxGw58E>)VCT8aOX)@j7PD?BRF+H_d zA8Mq2d_2gO_;|g7%3mBdx%nxjIjMF<96-|t<8 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/_compat.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/_compat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be19479242570d639521ecf5cf9a41087e63c754 GIT binary patch literal 32753 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 M8nm0gQ^o`S9|jsLZvX%Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/applications.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/applications.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f647bad0ee59d4b1fa7c3ddd685387ee85aab44a GIT binary patch literal 92513 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/cli.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/cli.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f535ed5fb84b4a7403b730f1f6640234027e15b GIT binary patch literal 764 zcmaJ<&1(}u6o0cH$>wVVO-`Pcrk8+rEkzU&Z$j-M2ldj3mTh)SS9fQZ*-2uHLM%O` z;K@rpd#FhNnF=1lLO>7%@v@Lh=*c(9wt}K>=Kbb<&U^EikCjRhke+`3+5JEOzDebR zv`m=ZLg5$+;DSqh2uNEYz$y)(>I!h3fUC5XEnwOJUaDI#Ag=CehgzGs%0p=8e#mQ@ zB+&xLW342|spxUm$u6HCDx&0Rgm4UEZd^cYx#Tqn>CNaBoM5M?$O|GM^a~l_PwxQ{ zmyrM`7NX9)(sfrk2>H)-xv-PUKmgFbEvxUbP~hI_UEl+I`>#8nAtY5aQXgyA&;Hu8ulc1E2&w;uakVzwkV~f4XR}#q=%kv$KOin+m4jRXj`B72 I9jU3m07(A5PXGV_ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/concurrency.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/concurrency.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30e034c9444911c9610d58e00ab17a20e7e060ed GIT binary patch literal 1863 zcmbVMTWcFv5S~3}SNBUS$w^x3wkC0klGeibt%QPWLIO!cASNaPcUeov&f0qsM@N=L z<>I!X_#qF5hQ@^!^ibRu=OI6#p?^RLhKL12piml0VS^h8dFmX=vMgMe($VbfoY|Rk z`@Yc+@puGKKK|{G`E?E8S2^fPaL?I&fX+QALQ%26R`QA>ePR)t=BcgbRa?tz?HIKJ z`5=B%t)LyshuSgC3fqx zP>e9j;zc?~da*gR7`?4-V$RlnUOrKz*C88wCL>wJOB>~yQz*EOV9UZb9AlpGEcFr- zGJKIaj2pt`UShJ7@lhwk3r^Ka?1sUw;uOhAqhu6JQM+Q=roeK=8sf zSaMwpKMe4Sb0~OH1}ly*Eq%`9WuX^byJRuJJfcr|q+oji&P0Vfh5akQ%}Zz~0oeT- zqnANJ5X6D+MWz4JR+KOZDo@>!IxJvuNBT3rKmb3XH{c%qQk@2TBcvkG%>`IcyM6;n zaaeHX{cMCAe|6W9$~zYWQAm*7s9k|{n7v)@~fGUMBs@n+(XhQ^y+#qwn4 zj{78W=5gXoE0(x(c_XtS8dDF>`xKJzJO`4D{3VSKB>bPv%NJ>g4f+t&GCi{sAJ|Eq zxSM;DI{P?vwskCZH~QUFWB8ltZ>Jl^j|2DL`uSa4Gkp%%Oeb*7bOP6mA8npfHGz9W zvqt;~983A2gfp#FdhMc5(Q6O?$-G4I+(c@U(qE{C zgKW}^?BRh}a@qJ^0LfxH^IUR(%U0yFPrYQDdZYWy<0<(`veX+ypgH~%2{w8FY#x#c zlEGXy506SC@%;&Q(E=Yr^D1=Sc8e8@eZWU>DBGa?CmKATqO@S5*{>~lzj?Gih2zbx zwqUr~uPwON?AI1tYWAy7h(ZvQBTNVa@zv?Isn2F^&#V$Z0A$c7CzMDlbbOs}hhFz7 k4xVc1^$$1H^-J5@kgs9Dhpu@}v0_`vw2OLSei~2wH@)=Br~m)} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/datastructures.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/datastructures.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a95409a7a951b2a2bd49997a7539da994a67b884 GIT binary patch literal 9392 zcmd5iTWlOhax?ql>~hKBYeh6B+)z#J2)kXbHS670A=TH9gzZSl~gX8`kKk84^uRQ7I zIqm_caT>34MLx$DL%C2foC_BtxkxdZixy+KSg|A5Q514QF`kR_h#S%q#m-!3F_}vi zyK-H{?p$|K%!#xwtoIaqbG@`4fqGxAkJh75@6YwqdJO6VxdB@5fO;yIqICi4J90Z{ zJr4E3+z_oN^qs|Bxn0HK+%V6DxO1G=d56=IWay(X$9)Pv_T&a>Ul;Use-wfq`1w7% zLmUw_@gtb+r||Pz_h>z2kJd}}9`l3G?qQ#RKZZJ<(Uhf zFs10aGOrUaa=M^8o-pGOi+&3iN>0Hv6y1wlUM>-@1L0N0@*=8YJL#y`dGYPjle3p+ zrsS)~yu_4gkvVmd6cuma9C6Ourold^6+_dB<%x}^tBPJG-u|V6vnUsgyeXG-rC`W6 z6}_M-j%msHvZ3POY2FK8x%4``Iwm#EBDM`x;jC#DPb-ds&C^8Dh=t9aZ8+{V+h;g z#)C21WlL;J*NJpsn-P+vqjWtRTkF=ueB>^d=e3?Y$y`^Q)5f$8piEH8zU?SU(x>dd z)0OMi1_G+oc2vQ5J77Ff8>eFrLcNFdYD1(?;~M(Zx=BA7&~}nk^QtxaVbAQk6Zr^c z`)RPIxgA^Z873*-G z1O9%pTRQ;zyPNC@+w*-8T&uAtuEt_RYv0yyAU@Xv)7RtI}N!K-! zzaFrfpm?fc03MN?MIv2i0?H_C2ElbIn&LQCVZQ7Dk|`;w3eJS0TgsATJK&@gOOq}x zJBuhM&U1WTH`VuG>Q#uPG*w@Av9j9cU$Y%3^r<4jA zr=S=Mrfz0bvzT?t;4BM@p7j^uFv@Lb)Bey04oGKiDaDdb*y3Eje!WEJM~BW^W>IpM zOQ_sJv1D3~6!=DlPci&~>nOgw6I8wlso`50iBc*_uSh=9csjvaPeOC1WZKU7{wx!5 zf10fc>J;oCFR2y*r%cyu98pd*gn4Iv*&#L?aXfu3eS(srL0ZHqTZZ(V{YW9(g%z^@ zgrpOLa!7x7i_w{BAbR#$A~ac#FG*vP&l=kR+l8T#FSR)Q{w@_0bWYzZ6PLj>x3n{J z{svJUX*@8WbjFJytCc~dffZhW(^_XniJUW@fZbSK*-P2N%q25V%^7>p!l=@K5o%>+ z7_k=FQCUZeS8`5y$BrN%F1N0K)6Ww zAY&>J?!6_ez&4=+tyE>3@VyvY+F3P-cEA&XAL70Tzb97#{E&Z*;eQSzLbG zvC1m!OJZkA%ho6`U+HP=pbVAeHE6Yu0{HbWxLXd7WW4*wA+FFm(V1d z?5s`J0Pphusd-ojK$TtuwUZ882jRoogWx#;b)&Gxu;m*7R>Y=7L>d{AoXHqK5r9eLTaAC7ES|hVUj^^Im{hE@W8y{QbE_z1!yKjQN9@{PQc7R*r~1m zE^Gl6T(^Y@T=~tmkZHFCq&}PSD%j4XCpR&Osit6LZ`r{489a z1^-SC7ikOkx{dS_71!&N5DnB4r$ zmR%eJ57Z*z@}Ef)M`Bs4J-W((oB5`K19qv0f7z^nf@o|i^;!R`o|@xLaFr4RQqP!<;3Wi@tFSr|;Pn;U8P)SE z*zj!t{?X& zDxP$OlXQ;Y`_m{*$l3?5+4O!-kY&7m%CeWBmQsf6x9lZl`Teq@`#l}93`q@HwuXSn ziXgz8lqbrv!g8>1w}3Ol!nCUw29x!|1;epW6fa7HcY1rE(WixBhlK~E*Gca!kSkg= zH4A-(g>K!#tz)6NST7(zFG_W2q4ikk%dBYxT?o1nhzQ<5a1nsl<===@qU*8@bEfAr zF4jqQJfki=q?k*HAP5S-$<&Vdb~XG7?`8+MZ?D#A-u;iX!b zkH7LX9PW(OxNww#$FwGJ;?P53t^Y?|YxbJ$e&cjy>`Zm+j5~Cu+I`lIV5vmTZY28e zO+TEw|Hj(!wd3yCxypg*>Vau@V7i)^aU)nNk(rII9ru>j!fRo7bh09ys!FHa!Bf?) zDK~aHt=o3ZZBK9@Co87fnCv9^6Rw zZY0IKQ?*d2ci?e2($)Qx15gV`yTqsA4lz-S0%C1|OLW&#SmT}rPHe&h0wqw{!Wjz$gdI)9R8jQ!H2W#B3Ko1w|t%dmL z@LFW;-Kum9PK4<2`mHa7FZ;h#zZ|Nbyj1<>9BpiX$6+A4^A07e#VCVtwD+F&@a5_b z&F!vlp#X5KuyAE#XsU*HrAxe#~C$I{j*ZCZa45B?oIP^kvtWMn( z-J>e((cnSngU=HT5*mNj!9VI~Ari^MVG4gJi)s-PgL)L|9a;?jw1(ditpmQ}ngGe6 zxYq{>Zl$a{7j;D?i>3~Lds_KhdS}2akiEDm`$L_Tq!l1qboAwVa@!fRF+qfRAV_&b zat|^`aIXaJL zomN4Eym}k?5|Be~##sb0@CNBcDchC+1OriYqEFBZV*qlS!+Sn^@LE96s84w78Z^Oy za1dU!-V#2*@lY@d4je+moAs5ccYY4EHoD_gZX>npZsdc+UHHeA5D%J`dkYFh1^caz zR4+0Q$uTB0Play2$bh)m{Y-IL=RcshEE0gQ?%wJ9=PTk!RUC1J5f%yXW{WD(=%~c6 zL!~VU*yhq=insY2!IcK?W$`SmwHd+UqHKPP_n!g*IXPbWH?PFQaOwsi@?9D>UT zaI)5Q1oH?~0FdON$!#l-EvN{#yfmvsMMtm>Kl@Js)Q?h#wL(!mOc8X0SA7Wn4PNaa z#z&=xqu4671L%5VFse|LG_o7NToKGkzEl`Ign;YstC+ZT|v4e|!9@n@jF}NGhG9)y`2j!g3L_ z=@Bmm7hkxSFiXMx!J;-AoY5c-LqQhPC9sBFE8@>tzDUkeDNejqxdqUNLZGI#|RS&bQ5)zZPDG z8xzFA-?mKXMJ?H11B9TD=WC$^AF6S`FEA9t(f+rfo8ynTT(-GvaNl%W%Lex?x3z4A z^Qz0Wlnw5<+gdibvu>_5iOOH4siw=imW=59f zrBb)>2VEE_)Ab^1k)SHjc$K;Z^4XsP`?Ej&>CoUJg8>8>SagA6efzgmkgS-Wac!bSL_OLngPfjx1I>)@S`9^jAjuQlR8c_);gNE7~bF8YA{ zy@lV$9|hP*{}@eMYJ_>!|;#sN7J5$yz>pcM?bA3=V`gPb~yY9Vk_&z?$^?wx)u{(;q3u=r(jdPT4>;+i+>sSX~ zfHhvnI`{&ti8@yN1z3}S)%!9n)?}Tj7tlOZ=RExatO)d_2zU5_Bk^s{vOr=-{)`=d zK4#T?9KXb_WMnR#k~Ig%zq7)}ESl>qpGpgC2BP-4?1~U`YQ76s?i@bNaUw5CS^yIl zvNA6&u_@jto9E@#ocK0P9BD*6Vn#etMFi&dE3CY%xv#8O0CH_*5<55M&Y%Y@%K^`Y?xGrWi&pa#ea{`;rpoJFrl*r3x z)?{ANJVs(cMs&~VY&IveGS6wYv$@otaeTz=n(xYuv!~~;U6@UN?~oR_o&^i1vph#7 zvLSh2Qb5j0ZbiszmYn7U@+)FCRUcnK#|nQN{6F6h;C)gcoABQKJb|pI_3Q=mv1J~$ zOG~+>oG7sJ#};u6iX|k?{O6_k9afC5uCB&;A$L2?-^pcG&~EWNeD+Q}lU|JH*W~3~ zc6wrJDlVmE{$QR>z0Ka@rT7vn$!tCy=d&r0U6dyBYvMQ%rCb1Y@>zMD$zkql zTH=|dOpcYkl*+Z`G}Mxq6^UP3$uO(Se3n_|G0Dv4vXU&a*c)mbScnX$zc8AOn&R5EmNE>>m5O&H>*v$sH2U=O0RRk2Vv z-~gi>)nS&PU-KLz=2o)YL0L@a^H^yShA$7I8V$^_S&qrGqQp;7K`yU|%mt1?mdKE0 z@?u)x!4#|j!_6>ITADB{aPs6y2AUivkYu&Lj8*j=8=9J!9Eus*LG)!R)X}LVB906g zWo}kV%5QQv*GFT@JwZRW-p;oEgSql$4LW+{%v?0 z&jP6#!a=8uW;^U~JOdRZHvllf>Bryx#(Z3PW6k+$PV)_%-g&%M<)nq?=4UUTo%`-W z^309owHsIFv=9!ETAxn}Y<|MjGjN`wYCnL;`$VqKWrWDsYpRcV23xnl? zf)ulhXkRT_oA8s1YsplGm8zpo0(8_>bJY;+fKF!`I@ktp8LM~Q8d5U>@d8wM6aG>P zzSi`O6?Y6m#U0z?x85wfXN+{2=BmD7#Xd~O#rEw_04-bp%{puG58TZU;Zn}^92 z%J`Jbz_bh<{thqF=o<@{=Z$&LKxY`umCmLzD;$4s-9+fh8pmekbP86An^laPIFEuq z0dCDWL?sF4ULaq?WT-D7VV1-Lw`JZ$a4F4aI9ggI*DMEr_v_@SV*It_sFG`v!wubo z&7@h0&DWOGnyqS@qD^X8FE5PYJu&GelUcw_Om0QS7L%59D;bWiub4}PV6tFvi5a7d zZ(hvZNprYV=0vnFm>!)R6Fry##563fyis$4xsZh=kU4$j!Z@&I)^aPfbs&q|@qnPPE)2RswmRp<=ZvRIbJRh#lR*5YwS%2C2~DmCm3&)(sURh)K-oQdYm zYvKxjv&sB{YO5qyvQXvTf0$}CHh>B5f7%Krs$dpSscQWyS!PMh2~@{waH5x*)}xOc1K6Rz;KU zeQqMXmlbNL|Nn-lYQ;#|4WO=j@d%#Z~q_1^DH zH1{$AqW#~i&t}(5{a_h;ILq9er`)NoO?tGXRwOwm)E3iwKl(~d%!vOhU0B8-R`r6# zCYgfLI~g{UTIPkdq{J@q?B(XUZqAsEca4K){b4f&OUr6nUZ$f3rz_?r(1dYq(zCXi zfW0V=1r|m_>TL%0cCb7N;J2g~)0wmk{Q@a1T)lYOkgmFnN#jVpX@tRs8W%g$CNYf>n}b=-SU)8u#b)9pXYsv%OK zU(*2my@PUaCk4KLT|ds6CQqQfpJJQSXWa*F-Cpo*Huj2IA+(ZNDhrX@>xHnZ;Ls7a z7HkE3!C7$p#{L92J*{(F_j8VdA9{+r0I{9ku z;Aml|61fe|wed8!vN&$S!#+))X1rZ|YqC2)0vGUiJpn5`ty=>4*JZ(j54pca8TzTY z_qo8zxYeT1u6jeYl3n$J^5{-kv%I_LjO^gbuQbHR8sZJ3ifihvOZFzItpykzO*-On zSoLYf#*@t^?0Q@8((Dh=D+8vnLpD2VlpEjXO_sU8t+&9)Z7Z~x=rn0{584~>th?}< zM$|p%bAU%)a^6{{^G}N%+L!k+X`)kK%tdxN7IGCuGYf?oa$qmwGP#C zVcUGTAzr^#f_yyEsXj~2CMz7iMb^Uw0vqOo>ybiuv#*BP_%>+~sm~){F&53%vyev< zg)r#T(A%3wkBn+pAF%I`{CX_~(!ZeI&Xm(k5%|^bvB=BzBV+w)U+*yWAyVjQvKg*l z?adr(>z9Yf^;v265$t+r_RcVoPwnV8Ld5iX6k4IH(6zVq3(;na0*~1p3eA!Lk5_l` z*uNfqdHV8P1NAO5_d@hXR?e~>eK)#lStWOEH^{2x2Hf;wPS)LAV(K|?%u-!}zM|*A zZH$-w12i~wsNjT{9y*}ExN{UC<>2^W**MyTZ4vlZ;7V0}R1O_A!;PX8Y91qOIkCua z^Kgs0#+-vQeAv2s( zFK29TahI3Mq#;#xUvB^{l#9yW~v3d%0RPIPDQO)0%qGX$4QNmLrD z+HBRMhV$$>_|o9a)-FZj)h+3~7Pu|t zvbC*?q}eeUb7^)w>k+>L9ZkH5;1Ys)1XmDT2B5i?$=o-Uy04NEg==&2@{1 zZGkLm-eeM5Y$<&!nbe#sd1w({+=mz;)Do}eYKp_TQS}ZLC>%&B>#3lGF`IwWGM*Z+f>N-bDQoEWuy8>Y&#l7j2|tL}`z0iudPL zSG!J}j;U>5uw;99?9s7}7RC1p1T{QfI{DGaru56$uVR((_|`%>JXHx#DgLSFhfaNZ z=-jhI=gNo9R}P)mi8U}qK{+&0@+A)aHqDc(M|ng!A0iDYfT-(sN*Iw%jvW z>6ug_)u7v;?76E&adm%meCyWlZNI6|T|SA%^ZU0_lT zMc)tpG`QJP4#g{>xDtwQhx=83P;Kp0BRv?}`_%4zYS*aRcTjKjM7*C70AC;|y7dV0 zcWguz-yj6Fb70e3={!(8za1P<{Sl+i^PXX~_kbR7g`g&YFA(U& zc8$QjlurB(FL1AfM>kXD@cv48KdL}UHHy-A5GnV>kZjnCWC47EKqp=x+daDnX@l3r-4Yoa6Q`}L*PIt>Lrs86-B#M_{(+}@Hx?2p=!Vhg9E_^il+sGF8arbY! zmCnOu*G$DVgScU!QuG=m*2}KZifa_JBWf^Ql#T2<&ml*z+Syg~Z+CWYO#kBO&yW7> z_y@<|`@!QM6#c5NP4R(=qaV(0x_)-?gNtSVSn=XlNU43J>QG!AJg5#&sUy?SWCLx`WCLx`WCLv_AGFut zlp5*UjW>vRgNQfSRto4La`1S`zwuT%6#G&Q_9*Ti!?gAfQy(4st?>Kn|2(I3zEO64 zr{emKPC`{vfdo1Ucv>hZo&^Ja>K}OKAJ`5tY9y-mLN^+&vL2n;kuvOU1?~W#2SCi` z543zi06=f5fo>A&1tI?A@)c))xb|S}Um_!l3j=hnkL;TZzx4ddQwi?hnl1<9m0(

    !yP+0d!-(3#5685rRX=q>=t?*5{y)VJ+xFQqnKFZ*H@Uko~dhf%}brB^qm z-#hX6gyJ7C0t|5vqdPs0@$F!^H2ZMv(OS`7w12tni@*SIjPC$-Xr$;=-7P-}{5Viz z%kF5!9fj_yTkW3l?QrLY?Y(1h`OlP7JMGYR9nJ z6;s<`T#u^JeK6GgPB63|F0lZ>P;)pX^!NYR61?0`{@Cxm+G_jbSm#y0O(DT6A*&L! zU_9i#YIi8zqgTG=P`>4Wc-d}){IcHx_%ZkV{IzrE&dpzooflakrnzzLmEj&<^QCf` z4BT76w;U3^%rn+OSM|nQgb5wiQ69eJ5pltV4@B~;@hOjpUq^_zPZrUI7x5fN^dZ0# z8x8M9m*K+@5l=UaCE6l{6>fUPcR4KP{QSOC5DK(v-x65KBMQb+7XoYs0~*7)*B5^*CZ z;weZ&4TCCvp&~L^(rQSW+U-C1jw>1dr1%(6E%2BA3tAP1jm4spHl-n`BzT|xRI*>$E2yMLF$a~j zE9RhET^1`0y1yC-5zDYbhIR*)bSUPak^#jWRPu)MO~Y>8o|}mSFO~Ew=AaTrF$a~z zmA!&Wrj)&cO2(DF!gF$3`MRLHEtalQd+F}u_08p92}wKele_!Itbc!hoYox>gN4!&cyOt7Om|_* z4XKK~y|ku#FzKxo`Y`3Eg&j(C27(^ItQO+%7n6Dr<00bkDBd0jdMl>eh@+(_>tT#X zh{IbvthZylgE-nshxJa3M~Nd;3hP}M@5cOTy$9pHMt&d0`;GVj#u)==5aUBe{xHTz zke8&|-Nj+m?o$E`1l1lag;je1^IgSAwa`_BJa2JUpTT+rfI>p0k&?VI`*>}0Y-<** zIlOheGIT`gJW^?U6;N2Y6ti&o9?aQt@clBTiq4ru+nq5(lMjkpzyiF zQyeSJmS#4FOUEnT{!PbbYHJ!AHK=&w700CR03@B5K?mu5UFkWYyndl5kM3{guv=g0pztb6ue`7$7X>g2cha|Q{6rYMVoH5211|N>>lv`0O&S{$M=QJ z<#p;dir+?BI#qY5)cz<~#kV281MvaqHYeh{Tbz2B;*Y#E{wT#iLV{6TF%4OqNZXCH z0q8al()I;Fj&3e&&OzI~QR#^*9q~%*WW_!8B4f2X^$SL8B&?)k fU`NJ1)$efXZyDI|iJQ}-OAQTaH0N$eKWX`I1*Y%g literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/exception_handlers.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/exception_handlers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d4ad79ba62a21855576941fbe802a08af0115a9 GIT binary patch literal 2343 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/logger.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/logger.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d96b0e3dc1b7a3f350a287fa5e2cc4e259bbb31 GIT binary patch literal 284 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/staticfiles.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/staticfiles.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b33115bf3b3930254cd00e496bc6bacc5ab0e664 GIT binary patch literal 260 zcmZ3^%ge<81aZ$^r@I2_#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ*d2gB$i|*yJhC27W-*3-4ZP>Ni51qEh$OW1G0cJX&{**W}xbo44*-oeg){4B^K$I zmzV3O=H_Q*rk3UBl$K=X=joTF=9TH^WG3ksRF-7q=Nao68tNBkmZa(yBqnDkrl%I` zrzHXnEy&bIGFq>o@)w6qZhlH>PO4oI2hajWATE{#5+9fu85wUd*j&Jdir9cE0G}dC A3IG5A literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/templating.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/templating.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc6adcbf32eebc62a797ce750ef6fe798ce1279d GIT binary patch literal 262 zcmZ3^%ge<81aZ$^r~3fu#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ}EF&=4B-sg{0;dProcRuS`EDGfBUovLquv&sfjUP`@~{BvrQ{F*!Ri zJ+)XrEfHvXL8d;!WW9pQUmP~M`6;D2sdhyiK=T=axL6iQd|+l|WW2%Pd;uFOVgsrG E06^kO@c;k- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/testclient.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/testclient.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87913731d0be9c887698147457adc42e9ebed242 GIT binary patch literal 257 zcmZ3^%ge<81aZ$^r#k`Z#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ*hgB7MD2ZWTxho_-QiT5-Bc8EXqkODM{5U0ZJr;C5o7VYF9FR25I@_uV0o}q+ecM zuAiElpOu+fmY-8vl9`{UUzVCzrk|6Uq+d{3l98WhtY>JbUz}Nzs#}nloSm4STCAUz z2sFJQQy*cnUP0wA4x8Nkl+v73yCM#t`HVnZEDIz)Ff%eT-e9o2fDIL~0aXA1s=Y|q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/types.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..342f4269f2b10679e03f84cb8fa52c075f8d61d3 GIT binary patch literal 917 zcmb7CyH6BB7@xg;AA3C4LNGScT;XnruSAFu4??&E8q{J7li~K`Slw54=Z?F|D=94K zyn=$lAV!KSEGYRCmgI`dR3s)QYGXo2<;)4;uJoI4zM0?mp2z1xA&(fn`SH8@UO?zO z2iK%tZ7!ynfLsmoha$7Ed1V;`1@fSQaTCqZ zK(4{OFg}Q!2^OisF|Ot?^;amUQFqOu51aD(XLZYwJaUO3Ps_D5_Lk z44YIdVc*A_K2T}Ns}L$~0HM;$W(-v2@-ettpj&RZaK}QH5!|u$o8=Br+EY7yKm?jSHO%{^V4Pn=THC zS4l>=&fq$=3Ir39B%>UODM_f&Z)zO}u!dtQdLg0mYFJrrd_fn?30;=$I!^4JogEv3 z=&c9!$gdH0D7y|}-S)jrJ8qKgD12be&Dp6(;C_rN?{F1Tdkd!o$DZ9kh7~t2wS^#Z zYd${+W>rncOi9ezs2t8!9`lE+#Wy9P*x02nlJB?HEbmLU( zK3UDo@|jugn&k{l^o*(9mA&Qm{E>WSSY5+v>AkTjrkHIv_wA#H9qIUKHvOn;K0XmM zbG|#a&@y^jVYjk(@56RmY?t=6gV}@hsC3ZyWOZgc=}D>6_-19J&%4@UOXeftpX)E5 Cyzs^V literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c816f34a47bcdc2e5b445cf23334419ccd2f2373 GIT binary patch literal 9396 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 Dl6`84 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/_compat.py b/venv/lib/python3.11/site-packages/fastapi/_compat.py new file mode 100644 index 0000000..c07e4a3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/_compat.py @@ -0,0 +1,659 @@ +from collections import deque +from copy import copy +from dataclasses import dataclass, is_dataclass +from enum import Enum +from functools import lru_cache +from typing import ( + Any, + Callable, + Deque, + Dict, + FrozenSet, + List, + Mapping, + Sequence, + Set, + Tuple, + Type, + Union, +) + +from fastapi.exceptions import RequestErrorModel +from fastapi.types import IncEx, ModelNameMap, UnionType +from pydantic import BaseModel, create_model +from pydantic.version import VERSION as PYDANTIC_VERSION +from starlette.datastructures import UploadFile +from typing_extensions import Annotated, Literal, get_args, get_origin + +PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")[:2]) +PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2 + + +sequence_annotation_to_type = { + Sequence: list, + List: list, + list: list, + Tuple: tuple, + tuple: tuple, + Set: set, + set: set, + FrozenSet: frozenset, + frozenset: frozenset, + Deque: deque, + deque: deque, +} + +sequence_types = tuple(sequence_annotation_to_type.keys()) + +Url: Type[Any] + +if PYDANTIC_V2: + from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError + from pydantic import TypeAdapter + from pydantic import ValidationError as ValidationError + from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined] + GetJsonSchemaHandler as GetJsonSchemaHandler, + ) + from pydantic._internal._typing_extra import eval_type_lenient + from pydantic._internal._utils import lenient_issubclass as lenient_issubclass + from pydantic.fields import FieldInfo + from pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema + from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue + from pydantic_core import CoreSchema as CoreSchema + from pydantic_core import PydanticUndefined, PydanticUndefinedType + from pydantic_core import Url as Url + + try: + from pydantic_core.core_schema import ( + with_info_plain_validator_function as with_info_plain_validator_function, + ) + except ImportError: # pragma: no cover + from pydantic_core.core_schema import ( + general_plain_validator_function as with_info_plain_validator_function, # noqa: F401 + ) + + RequiredParam = PydanticUndefined + Undefined = PydanticUndefined + UndefinedType = PydanticUndefinedType + evaluate_forwardref = eval_type_lenient + Validator = Any + + class BaseConfig: + pass + + class ErrorWrapper(Exception): + pass + + @dataclass + class ModelField: + field_info: FieldInfo + name: str + mode: Literal["validation", "serialization"] = "validation" + + @property + def alias(self) -> str: + a = self.field_info.alias + return a if a is not None else self.name + + @property + def required(self) -> bool: + return self.field_info.is_required() + + @property + def default(self) -> Any: + return self.get_default() + + @property + def type_(self) -> Any: + return self.field_info.annotation + + def __post_init__(self) -> None: + self._type_adapter: TypeAdapter[Any] = TypeAdapter( + Annotated[self.field_info.annotation, self.field_info] + ) + + def get_default(self) -> Any: + if self.field_info.is_required(): + return Undefined + return self.field_info.get_default(call_default_factory=True) + + def validate( + self, + value: Any, + values: Dict[str, Any] = {}, # noqa: B006 + *, + loc: Tuple[Union[int, str], ...] = (), + ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]: + try: + return ( + self._type_adapter.validate_python(value, from_attributes=True), + None, + ) + except ValidationError as exc: + return None, _regenerate_error_with_loc( + errors=exc.errors(include_url=False), loc_prefix=loc + ) + + def serialize( + self, + value: Any, + *, + mode: Literal["json", "python"] = "json", + include: Union[IncEx, None] = None, + exclude: Union[IncEx, None] = None, + by_alias: bool = True, + exclude_unset: bool = False, + exclude_defaults: bool = False, + exclude_none: bool = False, + ) -> Any: + # What calls this code passes a value that already called + # self._type_adapter.validate_python(value) + return self._type_adapter.dump_python( + value, + mode=mode, + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + + def __hash__(self) -> int: + # Each ModelField is unique for our purposes, to allow making a dict from + # ModelField to its JSON Schema. + return id(self) + + def get_annotation_from_field_info( + annotation: Any, field_info: FieldInfo, field_name: str + ) -> Any: + return annotation + + def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]: + return errors # type: ignore[return-value] + + def _model_rebuild(model: Type[BaseModel]) -> None: + model.model_rebuild() + + def _model_dump( + model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any + ) -> Any: + return model.model_dump(mode=mode, **kwargs) + + def _get_model_config(model: BaseModel) -> Any: + return model.model_config + + def get_schema_from_model_field( + *, + field: ModelField, + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + field_mapping: Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + separate_input_output_schemas: bool = True, + ) -> Dict[str, Any]: + override_mode: Union[Literal["validation"], None] = ( + None if separate_input_output_schemas else "validation" + ) + # This expects that GenerateJsonSchema was already used to generate the definitions + json_schema = field_mapping[(field, override_mode or field.mode)] + if "$ref" not in json_schema: + # TODO remove when deprecating Pydantic v1 + # Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207 + json_schema["title"] = ( + field.field_info.title or field.alias.title().replace("_", " ") + ) + return json_schema + + def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap: + return {} + + def get_definitions( + *, + fields: List[ModelField], + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + separate_input_output_schemas: bool = True, + ) -> Tuple[ + Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + Dict[str, Dict[str, Any]], + ]: + override_mode: Union[Literal["validation"], None] = ( + None if separate_input_output_schemas else "validation" + ) + inputs = [ + (field, override_mode or field.mode, field._type_adapter.core_schema) + for field in fields + ] + field_mapping, definitions = schema_generator.generate_definitions( + inputs=inputs + ) + return field_mapping, definitions # type: ignore[return-value] + + def is_scalar_field(field: ModelField) -> bool: + from fastapi import params + + return field_annotation_is_scalar( + field.field_info.annotation + ) and not isinstance(field.field_info, params.Body) + + def is_sequence_field(field: ModelField) -> bool: + return field_annotation_is_sequence(field.field_info.annotation) + + def is_scalar_sequence_field(field: ModelField) -> bool: + return field_annotation_is_scalar_sequence(field.field_info.annotation) + + def is_bytes_field(field: ModelField) -> bool: + return is_bytes_or_nonable_bytes_annotation(field.type_) + + def is_bytes_sequence_field(field: ModelField) -> bool: + return is_bytes_sequence_annotation(field.type_) + + def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo: + cls = type(field_info) + merged_field_info = cls.from_annotation(annotation) + new_field_info = copy(field_info) + new_field_info.metadata = merged_field_info.metadata + new_field_info.annotation = merged_field_info.annotation + return new_field_info + + def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]: + origin_type = ( + get_origin(field.field_info.annotation) or field.field_info.annotation + ) + assert issubclass(origin_type, sequence_types) # type: ignore[arg-type] + return sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return] + + def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]: + error = ValidationError.from_exception_data( + "Field required", [{"type": "missing", "loc": loc, "input": {}}] + ).errors(include_url=False)[0] + error["input"] = None + return error # type: ignore[return-value] + + def create_body_model( + *, fields: Sequence[ModelField], model_name: str + ) -> Type[BaseModel]: + field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields} + BodyModel: Type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload] + return BodyModel + + def get_model_fields(model: Type[BaseModel]) -> List[ModelField]: + return [ + ModelField(field_info=field_info, name=name) + for name, field_info in model.model_fields.items() + ] + +else: + from fastapi.openapi.constants import REF_PREFIX as REF_PREFIX + from pydantic import AnyUrl as Url # noqa: F401 + from pydantic import ( # type: ignore[assignment] + BaseConfig as BaseConfig, # noqa: F401 + ) + from pydantic import ValidationError as ValidationError # noqa: F401 + from pydantic.class_validators import ( # type: ignore[no-redef] + Validator as Validator, # noqa: F401 + ) + from pydantic.error_wrappers import ( # type: ignore[no-redef] + ErrorWrapper as ErrorWrapper, # noqa: F401 + ) + from pydantic.errors import MissingError + from pydantic.fields import ( # type: ignore[attr-defined] + SHAPE_FROZENSET, + SHAPE_LIST, + SHAPE_SEQUENCE, + SHAPE_SET, + SHAPE_SINGLETON, + SHAPE_TUPLE, + SHAPE_TUPLE_ELLIPSIS, + ) + from pydantic.fields import FieldInfo as FieldInfo + from pydantic.fields import ( # type: ignore[no-redef,attr-defined] + ModelField as ModelField, # noqa: F401 + ) + + # Keeping old "Required" functionality from Pydantic V1, without + # shadowing typing.Required. + RequiredParam: Any = Ellipsis # type: ignore[no-redef] + from pydantic.fields import ( # type: ignore[no-redef,attr-defined] + Undefined as Undefined, + ) + from pydantic.fields import ( # type: ignore[no-redef, attr-defined] + UndefinedType as UndefinedType, # noqa: F401 + ) + from pydantic.schema import ( + field_schema, + get_flat_models_from_fields, + get_model_name_map, + model_process_schema, + ) + from pydantic.schema import ( # type: ignore[no-redef] # noqa: F401 + get_annotation_from_field_info as get_annotation_from_field_info, + ) + from pydantic.typing import ( # type: ignore[no-redef] + evaluate_forwardref as evaluate_forwardref, # noqa: F401 + ) + from pydantic.utils import ( # type: ignore[no-redef] + lenient_issubclass as lenient_issubclass, # noqa: F401 + ) + + GetJsonSchemaHandler = Any # type: ignore[assignment,misc] + JsonSchemaValue = Dict[str, Any] # type: ignore[misc] + CoreSchema = Any # type: ignore[assignment,misc] + + sequence_shapes = { + SHAPE_LIST, + SHAPE_SET, + SHAPE_FROZENSET, + SHAPE_TUPLE, + SHAPE_SEQUENCE, + SHAPE_TUPLE_ELLIPSIS, + } + sequence_shape_to_type = { + SHAPE_LIST: list, + SHAPE_SET: set, + SHAPE_TUPLE: tuple, + SHAPE_SEQUENCE: list, + SHAPE_TUPLE_ELLIPSIS: list, + } + + @dataclass + class GenerateJsonSchema: # type: ignore[no-redef] + ref_template: str + + class PydanticSchemaGenerationError(Exception): # type: ignore[no-redef] + pass + + def with_info_plain_validator_function( # type: ignore[misc] + function: Callable[..., Any], + *, + ref: Union[str, None] = None, + metadata: Any = None, + serialization: Any = None, + ) -> Any: + return {} + + def get_model_definitions( + *, + flat_models: Set[Union[Type[BaseModel], Type[Enum]]], + model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str], + ) -> Dict[str, Any]: + definitions: Dict[str, Dict[str, Any]] = {} + for model in flat_models: + m_schema, m_definitions, m_nested_models = model_process_schema( + model, model_name_map=model_name_map, ref_prefix=REF_PREFIX + ) + definitions.update(m_definitions) + model_name = model_name_map[model] + if "description" in m_schema: + m_schema["description"] = m_schema["description"].split("\f")[0] + definitions[model_name] = m_schema + return definitions + + def is_pv1_scalar_field(field: ModelField) -> bool: + from fastapi import params + + field_info = field.field_info + if not ( + field.shape == SHAPE_SINGLETON # type: ignore[attr-defined] + and not lenient_issubclass(field.type_, BaseModel) + and not lenient_issubclass(field.type_, dict) + and not field_annotation_is_sequence(field.type_) + and not is_dataclass(field.type_) + and not isinstance(field_info, params.Body) + ): + return False + if field.sub_fields: # type: ignore[attr-defined] + if not all( + is_pv1_scalar_field(f) + for f in field.sub_fields # type: ignore[attr-defined] + ): + return False + return True + + def is_pv1_scalar_sequence_field(field: ModelField) -> bool: + if (field.shape in sequence_shapes) and not lenient_issubclass( # type: ignore[attr-defined] + field.type_, BaseModel + ): + if field.sub_fields is not None: # type: ignore[attr-defined] + for sub_field in field.sub_fields: # type: ignore[attr-defined] + if not is_pv1_scalar_field(sub_field): + return False + return True + if _annotation_is_sequence(field.type_): + return True + return False + + def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]: + use_errors: List[Any] = [] + for error in errors: + if isinstance(error, ErrorWrapper): + new_errors = ValidationError( # type: ignore[call-arg] + errors=[error], model=RequestErrorModel + ).errors() + use_errors.extend(new_errors) + elif isinstance(error, list): + use_errors.extend(_normalize_errors(error)) + else: + use_errors.append(error) + return use_errors + + def _model_rebuild(model: Type[BaseModel]) -> None: + model.update_forward_refs() + + def _model_dump( + model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any + ) -> Any: + return model.dict(**kwargs) + + def _get_model_config(model: BaseModel) -> Any: + return model.__config__ # type: ignore[attr-defined] + + def get_schema_from_model_field( + *, + field: ModelField, + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + field_mapping: Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + separate_input_output_schemas: bool = True, + ) -> Dict[str, Any]: + # This expects that GenerateJsonSchema was already used to generate the definitions + return field_schema( # type: ignore[no-any-return] + field, model_name_map=model_name_map, ref_prefix=REF_PREFIX + )[0] + + def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap: + models = get_flat_models_from_fields(fields, known_models=set()) + return get_model_name_map(models) # type: ignore[no-any-return] + + def get_definitions( + *, + fields: List[ModelField], + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + separate_input_output_schemas: bool = True, + ) -> Tuple[ + Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + Dict[str, Dict[str, Any]], + ]: + models = get_flat_models_from_fields(fields, known_models=set()) + return {}, get_model_definitions( + flat_models=models, model_name_map=model_name_map + ) + + def is_scalar_field(field: ModelField) -> bool: + return is_pv1_scalar_field(field) + + def is_sequence_field(field: ModelField) -> bool: + return field.shape in sequence_shapes or _annotation_is_sequence(field.type_) # type: ignore[attr-defined] + + def is_scalar_sequence_field(field: ModelField) -> bool: + return is_pv1_scalar_sequence_field(field) + + def is_bytes_field(field: ModelField) -> bool: + return lenient_issubclass(field.type_, bytes) + + def is_bytes_sequence_field(field: ModelField) -> bool: + return field.shape in sequence_shapes and lenient_issubclass(field.type_, bytes) # type: ignore[attr-defined] + + def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo: + return copy(field_info) + + def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]: + return sequence_shape_to_type[field.shape](value) # type: ignore[no-any-return,attr-defined] + + def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]: + missing_field_error = ErrorWrapper(MissingError(), loc=loc) # type: ignore[call-arg] + new_error = ValidationError([missing_field_error], RequestErrorModel) + return new_error.errors()[0] # type: ignore[return-value] + + def create_body_model( + *, fields: Sequence[ModelField], model_name: str + ) -> Type[BaseModel]: + BodyModel = create_model(model_name) + for f in fields: + BodyModel.__fields__[f.name] = f # type: ignore[index] + return BodyModel + + def get_model_fields(model: Type[BaseModel]) -> List[ModelField]: + return list(model.__fields__.values()) # type: ignore[attr-defined] + + +def _regenerate_error_with_loc( + *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...] +) -> List[Dict[str, Any]]: + updated_loc_errors: List[Any] = [ + {**err, "loc": loc_prefix + err.get("loc", ())} + for err in _normalize_errors(errors) + ] + + return updated_loc_errors + + +def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool: + if lenient_issubclass(annotation, (str, bytes)): + return False + return lenient_issubclass(annotation, sequence_types) + + +def field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool: + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + for arg in get_args(annotation): + if field_annotation_is_sequence(arg): + return True + return False + return _annotation_is_sequence(annotation) or _annotation_is_sequence( + get_origin(annotation) + ) + + +def value_is_sequence(value: Any) -> bool: + return isinstance(value, sequence_types) and not isinstance(value, (str, bytes)) # type: ignore[arg-type] + + +def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool: + return ( + lenient_issubclass(annotation, (BaseModel, Mapping, UploadFile)) + or _annotation_is_sequence(annotation) + or is_dataclass(annotation) + ) + + +def field_annotation_is_complex(annotation: Union[Type[Any], None]) -> bool: + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + return any(field_annotation_is_complex(arg) for arg in get_args(annotation)) + + return ( + _annotation_is_complex(annotation) + or _annotation_is_complex(origin) + or hasattr(origin, "__pydantic_core_schema__") + or hasattr(origin, "__get_pydantic_core_schema__") + ) + + +def field_annotation_is_scalar(annotation: Any) -> bool: + # handle Ellipsis here to make tuple[int, ...] work nicely + return annotation is Ellipsis or not field_annotation_is_complex(annotation) + + +def field_annotation_is_scalar_sequence(annotation: Union[Type[Any], None]) -> bool: + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + at_least_one_scalar_sequence = False + for arg in get_args(annotation): + if field_annotation_is_scalar_sequence(arg): + at_least_one_scalar_sequence = True + continue + elif not field_annotation_is_scalar(arg): + return False + return at_least_one_scalar_sequence + return field_annotation_is_sequence(annotation) and all( + field_annotation_is_scalar(sub_annotation) + for sub_annotation in get_args(annotation) + ) + + +def is_bytes_or_nonable_bytes_annotation(annotation: Any) -> bool: + if lenient_issubclass(annotation, bytes): + return True + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + for arg in get_args(annotation): + if lenient_issubclass(arg, bytes): + return True + return False + + +def is_uploadfile_or_nonable_uploadfile_annotation(annotation: Any) -> bool: + if lenient_issubclass(annotation, UploadFile): + return True + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + for arg in get_args(annotation): + if lenient_issubclass(arg, UploadFile): + return True + return False + + +def is_bytes_sequence_annotation(annotation: Any) -> bool: + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + at_least_one = False + for arg in get_args(annotation): + if is_bytes_sequence_annotation(arg): + at_least_one = True + continue + return at_least_one + return field_annotation_is_sequence(annotation) and all( + is_bytes_or_nonable_bytes_annotation(sub_annotation) + for sub_annotation in get_args(annotation) + ) + + +def is_uploadfile_sequence_annotation(annotation: Any) -> bool: + origin = get_origin(annotation) + if origin is Union or origin is UnionType: + at_least_one = False + for arg in get_args(annotation): + if is_uploadfile_sequence_annotation(arg): + at_least_one = True + continue + return at_least_one + return field_annotation_is_sequence(annotation) and all( + is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation) + for sub_annotation in get_args(annotation) + ) + + +@lru_cache +def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]: + return get_model_fields(model) diff --git a/venv/lib/python3.11/site-packages/fastapi/applications.py b/venv/lib/python3.11/site-packages/fastapi/applications.py new file mode 100644 index 0000000..6d427cd --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/applications.py @@ -0,0 +1,4585 @@ +from enum import Enum +from typing import ( + Any, + Awaitable, + Callable, + Coroutine, + Dict, + List, + Optional, + Sequence, + Type, + TypeVar, + Union, +) + +from fastapi import routing +from fastapi.datastructures import Default, DefaultPlaceholder +from fastapi.exception_handlers import ( + http_exception_handler, + request_validation_exception_handler, + websocket_request_validation_exception_handler, +) +from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError +from fastapi.logger import logger +from fastapi.openapi.docs import ( + get_redoc_html, + get_swagger_ui_html, + get_swagger_ui_oauth2_redirect_html, +) +from fastapi.openapi.utils import get_openapi +from fastapi.params import Depends +from fastapi.types import DecoratedCallable, IncEx +from fastapi.utils import generate_unique_id +from starlette.applications import Starlette +from starlette.datastructures import State +from starlette.exceptions import HTTPException +from starlette.middleware import Middleware +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.requests import Request +from starlette.responses import HTMLResponse, JSONResponse, Response +from starlette.routing import BaseRoute +from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send +from typing_extensions import Annotated, Doc, deprecated + +AppType = TypeVar("AppType", bound="FastAPI") + + +class FastAPI(Starlette): + """ + `FastAPI` app class, the main entrypoint to use FastAPI. + + Read more in the + [FastAPI docs for First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/). + + ## Example + + ```python + from fastapi import FastAPI + + app = FastAPI() + ``` + """ + + def __init__( + self: AppType, + *, + debug: Annotated[ + bool, + Doc( + """ + Boolean indicating if debug tracebacks should be returned on server + errors. + + Read more in the + [Starlette docs for Applications](https://www.starlette.io/applications/#instantiating-the-application). + """ + ), + ] = False, + routes: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + **Note**: you probably shouldn't use this parameter, it is inherited + from Starlette and supported for compatibility. + + --- + + A list of routes to serve incoming HTTP and WebSocket requests. + """ + ), + deprecated( + """ + You normally wouldn't use this parameter with FastAPI, it is inherited + from Starlette and supported for compatibility. + + In FastAPI, you normally would use the *path operation methods*, + like `app.get()`, `app.post()`, etc. + """ + ), + ] = None, + title: Annotated[ + str, + Doc( + """ + The title of the API. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(title="ChimichangApp") + ``` + """ + ), + ] = "FastAPI", + summary: Annotated[ + Optional[str], + Doc( + """ + A short summary of the API. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(summary="Deadpond's favorite app. Nuff said.") + ``` + """ + ), + ] = None, + description: Annotated[ + str, + Doc( + ''' + A description of the API. Supports Markdown (using + [CommonMark syntax](https://commonmark.org/)). + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI( + description=""" + ChimichangApp API helps you do awesome stuff. 🚀 + + ## Items + + You can **read items**. + + ## Users + + You will be able to: + + * **Create users** (_not implemented_). + * **Read users** (_not implemented_). + + """ + ) + ``` + ''' + ), + ] = "", + version: Annotated[ + str, + Doc( + """ + The version of the API. + + **Note** This is the version of your application, not the version of + the OpenAPI specification nor the version of FastAPI being used. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(version="0.0.1") + ``` + """ + ), + ] = "0.1.0", + openapi_url: Annotated[ + Optional[str], + Doc( + """ + The URL where the OpenAPI schema will be served from. + + If you set it to `None`, no OpenAPI schema will be served publicly, and + the default automatic endpoints `/docs` and `/redoc` will also be + disabled. + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#openapi-url). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(openapi_url="/api/v1/openapi.json") + ``` + """ + ), + ] = "/openapi.json", + openapi_tags: Annotated[ + Optional[List[Dict[str, Any]]], + Doc( + """ + A list of tags used by OpenAPI, these are the same `tags` you can set + in the *path operations*, like: + + * `@app.get("/users/", tags=["users"])` + * `@app.get("/items/", tags=["items"])` + + The order of the tags can be used to specify the order shown in + tools like Swagger UI, used in the automatic path `/docs`. + + It's not required to specify all the tags used. + + The tags that are not declared MAY be organized randomly or based + on the tools' logic. Each tag name in the list MUST be unique. + + The value of each item is a `dict` containing: + + * `name`: The name of the tag. + * `description`: A short description of the tag. + [CommonMark syntax](https://commonmark.org/) MAY be used for rich + text representation. + * `externalDocs`: Additional external documentation for this tag. If + provided, it would contain a `dict` with: + * `description`: A short description of the target documentation. + [CommonMark syntax](https://commonmark.org/) MAY be used for + rich text representation. + * `url`: The URL for the target documentation. Value MUST be in + the form of a URL. + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags). + + **Example** + + ```python + from fastapi import FastAPI + + tags_metadata = [ + { + "name": "users", + "description": "Operations with users. The **login** logic is also here.", + }, + { + "name": "items", + "description": "Manage items. So _fancy_ they have their own docs.", + "externalDocs": { + "description": "Items external docs", + "url": "https://fastapi.tiangolo.com/", + }, + }, + ] + + app = FastAPI(openapi_tags=tags_metadata) + ``` + """ + ), + ] = None, + servers: Annotated[ + Optional[List[Dict[str, Union[str, Any]]]], + Doc( + """ + A `list` of `dict`s with connectivity information to a target server. + + You would use it, for example, if your application is served from + different domains and you want to use the same Swagger UI in the + browser to interact with each of them (instead of having multiple + browser tabs open). Or if you want to leave fixed the possible URLs. + + If the servers `list` is not provided, or is an empty `list`, the + default value would be a `dict` with a `url` value of `/`. + + Each item in the `list` is a `dict` containing: + + * `url`: A URL to the target host. This URL supports Server Variables + and MAY be relative, to indicate that the host location is relative + to the location where the OpenAPI document is being served. Variable + substitutions will be made when a variable is named in `{`brackets`}`. + * `description`: An optional string describing the host designated by + the URL. [CommonMark syntax](https://commonmark.org/) MAY be used for + rich text representation. + * `variables`: A `dict` between a variable name and its value. The value + is used for substitution in the server's URL template. + + Read more in the + [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI( + servers=[ + {"url": "https://stag.example.com", "description": "Staging environment"}, + {"url": "https://prod.example.com", "description": "Production environment"}, + ] + ) + ``` + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of global dependencies, they will be applied to each + *path operation*, including in sub-routers. + + Read more about it in the + [FastAPI docs for Global Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/global-dependencies/). + + **Example** + + ```python + from fastapi import Depends, FastAPI + + from .dependencies import func_dep_1, func_dep_2 + + app = FastAPI(dependencies=[Depends(func_dep_1), Depends(func_dep_2)]) + ``` + """ + ), + ] = None, + default_response_class: Annotated[ + Type[Response], + Doc( + """ + The default response class to be used. + + Read more in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). + + **Example** + + ```python + from fastapi import FastAPI + from fastapi.responses import ORJSONResponse + + app = FastAPI(default_response_class=ORJSONResponse) + ``` + """ + ), + ] = Default(JSONResponse), + redirect_slashes: Annotated[ + bool, + Doc( + """ + Whether to detect and redirect slashes in URLs when the client doesn't + use the same format. + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(redirect_slashes=True) # the default + + @app.get("/items/") + async def read_items(): + return [{"item_id": "Foo"}] + ``` + + With this app, if a client goes to `/items` (without a trailing slash), + they will be automatically redirected with an HTTP status code of 307 + to `/items/`. + """ + ), + ] = True, + docs_url: Annotated[ + Optional[str], + Doc( + """ + The path to the automatic interactive API documentation. + It is handled in the browser by Swagger UI. + + The default URL is `/docs`. You can disable it by setting it to `None`. + + If `openapi_url` is set to `None`, this will be automatically disabled. + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(docs_url="/documentation", redoc_url=None) + ``` + """ + ), + ] = "/docs", + redoc_url: Annotated[ + Optional[str], + Doc( + """ + The path to the alternative automatic interactive API documentation + provided by ReDoc. + + The default URL is `/redoc`. You can disable it by setting it to `None`. + + If `openapi_url` is set to `None`, this will be automatically disabled. + + Read more in the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(docs_url="/documentation", redoc_url="redocumentation") + ``` + """ + ), + ] = "/redoc", + swagger_ui_oauth2_redirect_url: Annotated[ + Optional[str], + Doc( + """ + The OAuth2 redirect endpoint for the Swagger UI. + + By default it is `/docs/oauth2-redirect`. + + This is only used if you use OAuth2 (with the "Authorize" button) + with Swagger UI. + """ + ), + ] = "/docs/oauth2-redirect", + swagger_ui_init_oauth: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + OAuth2 configuration for the Swagger UI, by default shown at `/docs`. + + Read more about the available configuration options in the + [Swagger UI docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). + """ + ), + ] = None, + middleware: Annotated[ + Optional[Sequence[Middleware]], + Doc( + """ + List of middleware to be added when creating the application. + + In FastAPI you would normally do this with `app.add_middleware()` + instead. + + Read more in the + [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/). + """ + ), + ] = None, + exception_handlers: Annotated[ + Optional[ + Dict[ + Union[int, Type[Exception]], + Callable[[Request, Any], Coroutine[Any, Any, Response]], + ] + ], + Doc( + """ + A dictionary with handlers for exceptions. + + In FastAPI, you would normally use the decorator + `@app.exception_handler()`. + + Read more in the + [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). + """ + ), + ] = None, + on_startup: Annotated[ + Optional[Sequence[Callable[[], Any]]], + Doc( + """ + A list of startup event handler functions. + + You should instead use the `lifespan` handlers. + + Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). + """ + ), + ] = None, + on_shutdown: Annotated[ + Optional[Sequence[Callable[[], Any]]], + Doc( + """ + A list of shutdown event handler functions. + + You should instead use the `lifespan` handlers. + + Read more in the + [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). + """ + ), + ] = None, + lifespan: Annotated[ + Optional[Lifespan[AppType]], + Doc( + """ + A `Lifespan` context manager handler. This replaces `startup` and + `shutdown` functions with a single context manager. + + Read more in the + [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). + """ + ), + ] = None, + terms_of_service: Annotated[ + Optional[str], + Doc( + """ + A URL to the Terms of Service for your API. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more at the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + app = FastAPI(terms_of_service="http://example.com/terms/") + ``` + """ + ), + ] = None, + contact: Annotated[ + Optional[Dict[str, Union[str, Any]]], + Doc( + """ + A dictionary with the contact information for the exposed API. + + It can contain several fields. + + * `name`: (`str`) The name of the contact person/organization. + * `url`: (`str`) A URL pointing to the contact information. MUST be in + the format of a URL. + * `email`: (`str`) The email address of the contact person/organization. + MUST be in the format of an email address. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more at the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + app = FastAPI( + contact={ + "name": "Deadpoolio the Amazing", + "url": "http://x-force.example.com/contact/", + "email": "dp@x-force.example.com", + } + ) + ``` + """ + ), + ] = None, + license_info: Annotated[ + Optional[Dict[str, Union[str, Any]]], + Doc( + """ + A dictionary with the license information for the exposed API. + + It can contain several fields. + + * `name`: (`str`) **REQUIRED** (if a `license_info` is set). The + license name used for the API. + * `identifier`: (`str`) An [SPDX](https://spdx.dev/) license expression + for the API. The `identifier` field is mutually exclusive of the `url` + field. Available since OpenAPI 3.1.0, FastAPI 0.99.0. + * `url`: (`str`) A URL to the license used for the API. This MUST be + the format of a URL. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more at the + [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). + + **Example** + + ```python + app = FastAPI( + license_info={ + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html", + } + ) + ``` + """ + ), + ] = None, + openapi_prefix: Annotated[ + str, + Doc( + """ + A URL prefix for the OpenAPI URL. + """ + ), + deprecated( + """ + "openapi_prefix" has been deprecated in favor of "root_path", which + follows more closely the ASGI standard, is simpler, and more + automatic. + """ + ), + ] = "", + root_path: Annotated[ + str, + Doc( + """ + A path prefix handled by a proxy that is not seen by the application + but is seen by external clients, which affects things like Swagger UI. + + Read more about it at the + [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(root_path="/api/v1") + ``` + """ + ), + ] = "", + root_path_in_servers: Annotated[ + bool, + Doc( + """ + To disable automatically generating the URLs in the `servers` field + in the autogenerated OpenAPI using the `root_path`. + + Read more about it in the + [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root_path). + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI(root_path_in_servers=False) + ``` + """ + ), + ] = True, + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses to be shown in OpenAPI. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/). + + And in the + [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + OpenAPI callbacks that should apply to all *path operations*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + webhooks: Annotated[ + Optional[routing.APIRouter], + Doc( + """ + Add OpenAPI webhooks. This is similar to `callbacks` but it doesn't + depend on specific *path operations*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + **Note**: This is available since OpenAPI 3.1.0, FastAPI 0.99.0. + + Read more about it in the + [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark all *path operations* as deprecated. You probably don't need it, + but it's available. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) all the *path operations* in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + swagger_ui_parameters: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Parameters to configure Swagger UI, the autogenerated interactive API + documentation (by default at `/docs`). + + Read more about it in the + [FastAPI docs about how to Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + separate_input_output_schemas: Annotated[ + bool, + Doc( + """ + Whether to generate separate OpenAPI schemas for request body and + response body when the results would be more precise. + + This is particularly useful when automatically generating clients. + + For example, if you have a model like: + + ```python + from pydantic import BaseModel + + class Item(BaseModel): + name: str + tags: list[str] = [] + ``` + + When `Item` is used for input, a request body, `tags` is not required, + the client doesn't have to provide it. + + But when using `Item` for output, for a response body, `tags` is always + available because it has a default value, even if it's just an empty + list. So, the client should be able to always expect it. + + In this case, there would be two different schemas, one for input and + another one for output. + """ + ), + ] = True, + **extra: Annotated[ + Any, + Doc( + """ + Extra keyword arguments to be stored in the app, not used by FastAPI + anywhere. + """ + ), + ], + ) -> None: + self.debug = debug + self.title = title + self.summary = summary + self.description = description + self.version = version + self.terms_of_service = terms_of_service + self.contact = contact + self.license_info = license_info + self.openapi_url = openapi_url + self.openapi_tags = openapi_tags + self.root_path_in_servers = root_path_in_servers + self.docs_url = docs_url + self.redoc_url = redoc_url + self.swagger_ui_oauth2_redirect_url = swagger_ui_oauth2_redirect_url + self.swagger_ui_init_oauth = swagger_ui_init_oauth + self.swagger_ui_parameters = swagger_ui_parameters + self.servers = servers or [] + self.separate_input_output_schemas = separate_input_output_schemas + self.extra = extra + self.openapi_version: Annotated[ + str, + Doc( + """ + The version string of OpenAPI. + + FastAPI will generate OpenAPI version 3.1.0, and will output that as + the OpenAPI version. But some tools, even though they might be + compatible with OpenAPI 3.1.0, might not recognize it as a valid. + + So you could override this value to trick those tools into using + the generated OpenAPI. Have in mind that this is a hack. But if you + avoid using features added in OpenAPI 3.1.0, it might work for your + use case. + + This is not passed as a parameter to the `FastAPI` class to avoid + giving the false idea that FastAPI would generate a different OpenAPI + schema. It is only available as an attribute. + + **Example** + + ```python + from fastapi import FastAPI + + app = FastAPI() + + app.openapi_version = "3.0.2" + ``` + """ + ), + ] = "3.1.0" + self.openapi_schema: Optional[Dict[str, Any]] = None + if self.openapi_url: + assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'" + assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'" + # TODO: remove when discarding the openapi_prefix parameter + if openapi_prefix: + logger.warning( + '"openapi_prefix" has been deprecated in favor of "root_path", which ' + "follows more closely the ASGI standard, is simpler, and more " + "automatic. Check the docs at " + "https://fastapi.tiangolo.com/advanced/sub-applications/" + ) + self.webhooks: Annotated[ + routing.APIRouter, + Doc( + """ + The `app.webhooks` attribute is an `APIRouter` with the *path + operations* that will be used just for documentation of webhooks. + + Read more about it in the + [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/). + """ + ), + ] = webhooks or routing.APIRouter() + self.root_path = root_path or openapi_prefix + self.state: Annotated[ + State, + Doc( + """ + A state object for the application. This is the same object for the + entire application, it doesn't change from request to request. + + You normally wouldn't use this in FastAPI, for most of the cases you + would instead use FastAPI dependencies. + + This is simply inherited from Starlette. + + Read more about it in the + [Starlette docs for Applications](https://www.starlette.io/applications/#storing-state-on-the-app-instance). + """ + ), + ] = State() + self.dependency_overrides: Annotated[ + Dict[Callable[..., Any], Callable[..., Any]], + Doc( + """ + A dictionary with overrides for the dependencies. + + Each key is the original dependency callable, and the value is the + actual dependency that should be called. + + This is for testing, to replace expensive dependencies with testing + versions. + + Read more about it in the + [FastAPI docs for Testing Dependencies with Overrides](https://fastapi.tiangolo.com/advanced/testing-dependencies/). + """ + ), + ] = {} + self.router: routing.APIRouter = routing.APIRouter( + routes=routes, + redirect_slashes=redirect_slashes, + dependency_overrides_provider=self, + on_startup=on_startup, + on_shutdown=on_shutdown, + lifespan=lifespan, + default_response_class=default_response_class, + dependencies=dependencies, + callbacks=callbacks, + deprecated=deprecated, + include_in_schema=include_in_schema, + responses=responses, + generate_unique_id_function=generate_unique_id_function, + ) + self.exception_handlers: Dict[ + Any, Callable[[Request, Any], Union[Response, Awaitable[Response]]] + ] = {} if exception_handlers is None else dict(exception_handlers) + self.exception_handlers.setdefault(HTTPException, http_exception_handler) + self.exception_handlers.setdefault( + RequestValidationError, request_validation_exception_handler + ) + self.exception_handlers.setdefault( + WebSocketRequestValidationError, + # Starlette still has incorrect type specification for the handlers + websocket_request_validation_exception_handler, # type: ignore + ) + + self.user_middleware: List[Middleware] = ( + [] if middleware is None else list(middleware) + ) + self.middleware_stack: Union[ASGIApp, None] = None + self.setup() + + def openapi(self) -> Dict[str, Any]: + """ + Generate the OpenAPI schema of the application. This is called by FastAPI + internally. + + The first time it is called it stores the result in the attribute + `app.openapi_schema`, and next times it is called, it just returns that same + result. To avoid the cost of generating the schema every time. + + If you need to modify the generated OpenAPI schema, you could modify it. + + Read more in the + [FastAPI docs for OpenAPI](https://fastapi.tiangolo.com/how-to/extending-openapi/). + """ + if not self.openapi_schema: + self.openapi_schema = get_openapi( + title=self.title, + version=self.version, + openapi_version=self.openapi_version, + summary=self.summary, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license_info=self.license_info, + routes=self.routes, + webhooks=self.webhooks.routes, + tags=self.openapi_tags, + servers=self.servers, + separate_input_output_schemas=self.separate_input_output_schemas, + ) + return self.openapi_schema + + def setup(self) -> None: + if self.openapi_url: + urls = (server_data.get("url") for server_data in self.servers) + server_urls = {url for url in urls if url} + + async def openapi(req: Request) -> JSONResponse: + root_path = req.scope.get("root_path", "").rstrip("/") + if root_path not in server_urls: + if root_path and self.root_path_in_servers: + self.servers.insert(0, {"url": root_path}) + server_urls.add(root_path) + return JSONResponse(self.openapi()) + + self.add_route(self.openapi_url, openapi, include_in_schema=False) + if self.openapi_url and self.docs_url: + + async def swagger_ui_html(req: Request) -> HTMLResponse: + root_path = req.scope.get("root_path", "").rstrip("/") + openapi_url = root_path + self.openapi_url + oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url + if oauth2_redirect_url: + oauth2_redirect_url = root_path + oauth2_redirect_url + return get_swagger_ui_html( + openapi_url=openapi_url, + title=f"{self.title} - Swagger UI", + oauth2_redirect_url=oauth2_redirect_url, + init_oauth=self.swagger_ui_init_oauth, + swagger_ui_parameters=self.swagger_ui_parameters, + ) + + self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False) + + if self.swagger_ui_oauth2_redirect_url: + + async def swagger_ui_redirect(req: Request) -> HTMLResponse: + return get_swagger_ui_oauth2_redirect_html() + + self.add_route( + self.swagger_ui_oauth2_redirect_url, + swagger_ui_redirect, + include_in_schema=False, + ) + if self.openapi_url and self.redoc_url: + + async def redoc_html(req: Request) -> HTMLResponse: + root_path = req.scope.get("root_path", "").rstrip("/") + openapi_url = root_path + self.openapi_url + return get_redoc_html( + openapi_url=openapi_url, title=f"{self.title} - ReDoc" + ) + + self.add_route(self.redoc_url, redoc_html, include_in_schema=False) + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + if self.root_path: + scope["root_path"] = self.root_path + await super().__call__(scope, receive, send) + + def add_api_route( + self, + path: str, + endpoint: Callable[..., Any], + *, + response_model: Any = Default(None), + status_code: Optional[int] = None, + tags: Optional[List[Union[str, Enum]]] = None, + dependencies: Optional[Sequence[Depends]] = None, + summary: Optional[str] = None, + description: Optional[str] = None, + response_description: str = "Successful Response", + responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, + deprecated: Optional[bool] = None, + methods: Optional[List[str]] = None, + operation_id: Optional[str] = None, + response_model_include: Optional[IncEx] = None, + response_model_exclude: Optional[IncEx] = None, + response_model_by_alias: bool = True, + response_model_exclude_unset: bool = False, + response_model_exclude_defaults: bool = False, + response_model_exclude_none: bool = False, + include_in_schema: bool = True, + response_class: Union[Type[Response], DefaultPlaceholder] = Default( + JSONResponse + ), + name: Optional[str] = None, + openapi_extra: Optional[Dict[str, Any]] = None, + generate_unique_id_function: Callable[[routing.APIRoute], str] = Default( + generate_unique_id + ), + ) -> None: + self.router.add_api_route( + path, + endpoint=endpoint, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=methods, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def api_route( + self, + path: str, + *, + response_model: Any = Default(None), + status_code: Optional[int] = None, + tags: Optional[List[Union[str, Enum]]] = None, + dependencies: Optional[Sequence[Depends]] = None, + summary: Optional[str] = None, + description: Optional[str] = None, + response_description: str = "Successful Response", + responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, + deprecated: Optional[bool] = None, + methods: Optional[List[str]] = None, + operation_id: Optional[str] = None, + response_model_include: Optional[IncEx] = None, + response_model_exclude: Optional[IncEx] = None, + response_model_by_alias: bool = True, + response_model_exclude_unset: bool = False, + response_model_exclude_defaults: bool = False, + response_model_exclude_none: bool = False, + include_in_schema: bool = True, + response_class: Type[Response] = Default(JSONResponse), + name: Optional[str] = None, + openapi_extra: Optional[Dict[str, Any]] = None, + generate_unique_id_function: Callable[[routing.APIRoute], str] = Default( + generate_unique_id + ), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.router.add_api_route( + path, + func, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=methods, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + return func + + return decorator + + def add_api_websocket_route( + self, + path: str, + endpoint: Callable[..., Any], + name: Optional[str] = None, + *, + dependencies: Optional[Sequence[Depends]] = None, + ) -> None: + self.router.add_api_websocket_route( + path, + endpoint, + name=name, + dependencies=dependencies, + ) + + def websocket( + self, + path: Annotated[ + str, + Doc( + """ + WebSocket path. + """ + ), + ], + name: Annotated[ + Optional[str], + Doc( + """ + A name for the WebSocket. Only used internally. + """ + ), + ] = None, + *, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be used for this + WebSocket. + + Read more about it in the + [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). + """ + ), + ] = None, + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Decorate a WebSocket function. + + Read more about it in the + [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). + + **Example** + + ```python + from fastapi import FastAPI, WebSocket + + app = FastAPI() + + @app.websocket("/ws") + async def websocket_endpoint(websocket: WebSocket): + await websocket.accept() + while True: + data = await websocket.receive_text() + await websocket.send_text(f"Message text was: {data}") + ``` + """ + + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_api_websocket_route( + path, + func, + name=name, + dependencies=dependencies, + ) + return func + + return decorator + + def include_router( + self, + router: Annotated[routing.APIRouter, Doc("The `APIRouter` to include.")], + *, + prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to all the *path operations* in this + router. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to all the + *path operations* in this router. + + Read more about it in the + [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + + **Example** + + ```python + from fastapi import Depends, FastAPI + + from .dependencies import get_token_header + from .internal import admin + + app = FastAPI() + + app.include_router( + admin.router, + dependencies=[Depends(get_token_header)], + ) + ``` + """ + ), + ] = None, + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses to be shown in OpenAPI. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/). + + And in the + [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark all the *path operations* in this router as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + **Example** + + ```python + from fastapi import FastAPI + + from .internal import old_api + + app = FastAPI() + + app.include_router( + old_api.router, + deprecated=True, + ) + ``` + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include (or not) all the *path operations* in this router in the + generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + **Example** + + ```python + from fastapi import FastAPI + + from .internal import old_api + + app = FastAPI() + + app.include_router( + old_api.router, + include_in_schema=False, + ) + ``` + """ + ), + ] = True, + default_response_class: Annotated[ + Type[Response], + Doc( + """ + Default response class to be used for the *path operations* in this + router. + + Read more in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). + + **Example** + + ```python + from fastapi import FastAPI + from fastapi.responses import ORJSONResponse + + from .internal import old_api + + app = FastAPI() + + app.include_router( + old_api.router, + default_response_class=ORJSONResponse, + ) + ``` + """ + ), + ] = Default(JSONResponse), + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> None: + """ + Include an `APIRouter` in the same app. + + Read more about it in the + [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/). + + ## Example + + ```python + from fastapi import FastAPI + + from .users import users_router + + app = FastAPI() + + app.include_router(users_router) + ``` + """ + self.router.include_router( + router, + prefix=prefix, + tags=tags, + dependencies=dependencies, + responses=responses, + deprecated=deprecated, + include_in_schema=include_in_schema, + default_response_class=default_response_class, + callbacks=callbacks, + generate_unique_id_function=generate_unique_id_function, + ) + + def get( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP GET operation. + + ## Example + + ```python + from fastapi import FastAPI + + app = FastAPI() + + @app.get("/items/") + def read_items(): + return [{"name": "Empanada"}, {"name": "Arepa"}] + ``` + """ + return self.router.get( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def put( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP PUT operation. + + ## Example + + ```python + from fastapi import FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + + @app.put("/items/{item_id}") + def replace_item(item_id: str, item: Item): + return {"message": "Item replaced", "id": item_id} + ``` + """ + return self.router.put( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def post( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP POST operation. + + ## Example + + ```python + from fastapi import FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + + @app.post("/items/") + def create_item(item: Item): + return {"message": "Item created"} + ``` + """ + return self.router.post( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def delete( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP DELETE operation. + + ## Example + + ```python + from fastapi import FastAPI + + app = FastAPI() + + @app.delete("/items/{item_id}") + def delete_item(item_id: str): + return {"message": "Item deleted"} + ``` + """ + return self.router.delete( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def options( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP OPTIONS operation. + + ## Example + + ```python + from fastapi import FastAPI + + app = FastAPI() + + @app.options("/items/") + def get_item_options(): + return {"additions": ["Aji", "Guacamole"]} + ``` + """ + return self.router.options( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def head( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP HEAD operation. + + ## Example + + ```python + from fastapi import FastAPI, Response + + app = FastAPI() + + @app.head("/items/", status_code=204) + def get_items_headers(response: Response): + response.headers["X-Cat-Dog"] = "Alone in the world" + ``` + """ + return self.router.head( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def patch( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP PATCH operation. + + ## Example + + ```python + from fastapi import FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + + @app.patch("/items/") + def update_item(item: Item): + return {"message": "Item updated in place"} + ``` + """ + return self.router.patch( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def trace( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[routing.APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP TRACE operation. + + ## Example + + ```python + from fastapi import FastAPI + + app = FastAPI() + + @app.put("/items/{item_id}") + def trace_item(item_id: str): + return None + ``` + """ + return self.router.trace( + path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def websocket_route( + self, path: str, name: Union[str, None] = None + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.router.add_websocket_route(path, func, name=name) + return func + + return decorator + + @deprecated( + """ + on_event is deprecated, use lifespan event handlers instead. + + Read more about it in the + [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/). + """ + ) + def on_event( + self, + event_type: Annotated[ + str, + Doc( + """ + The type of event. `startup` or `shutdown`. + """ + ), + ], + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add an event handler for the application. + + `on_event` is deprecated, use `lifespan` event handlers instead. + + Read more about it in the + [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated). + """ + return self.router.on_event(event_type) + + def middleware( + self, + middleware_type: Annotated[ + str, + Doc( + """ + The type of middleware. Currently only supports `http`. + """ + ), + ], + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a middleware to the application. + + Read more about it in the + [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/). + + ## Example + + ```python + import time + + from fastapi import FastAPI, Request + + app = FastAPI() + + + @app.middleware("http") + async def add_process_time_header(request: Request, call_next): + start_time = time.time() + response = await call_next(request) + process_time = time.time() - start_time + response.headers["X-Process-Time"] = str(process_time) + return response + ``` + """ + + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_middleware(BaseHTTPMiddleware, dispatch=func) + return func + + return decorator + + def exception_handler( + self, + exc_class_or_status_code: Annotated[ + Union[int, Type[Exception]], + Doc( + """ + The Exception class this would handle, or a status code. + """ + ), + ], + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add an exception handler to the app. + + Read more about it in the + [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). + + ## Example + + ```python + from fastapi import FastAPI, Request + from fastapi.responses import JSONResponse + + + class UnicornException(Exception): + def __init__(self, name: str): + self.name = name + + + app = FastAPI() + + + @app.exception_handler(UnicornException) + async def unicorn_exception_handler(request: Request, exc: UnicornException): + return JSONResponse( + status_code=418, + content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."}, + ) + ``` + """ + + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_exception_handler(exc_class_or_status_code, func) + return func + + return decorator diff --git a/venv/lib/python3.11/site-packages/fastapi/background.py b/venv/lib/python3.11/site-packages/fastapi/background.py new file mode 100644 index 0000000..203578a --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/background.py @@ -0,0 +1,59 @@ +from typing import Any, Callable + +from starlette.background import BackgroundTasks as StarletteBackgroundTasks +from typing_extensions import Annotated, Doc, ParamSpec + +P = ParamSpec("P") + + +class BackgroundTasks(StarletteBackgroundTasks): + """ + A collection of background tasks that will be called after a response has been + sent to the client. + + Read more about it in the + [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/). + + ## Example + + ```python + from fastapi import BackgroundTasks, FastAPI + + app = FastAPI() + + + def write_notification(email: str, message=""): + with open("log.txt", mode="w") as email_file: + content = f"notification for {email}: {message}" + email_file.write(content) + + + @app.post("/send-notification/{email}") + async def send_notification(email: str, background_tasks: BackgroundTasks): + background_tasks.add_task(write_notification, email, message="some notification") + return {"message": "Notification sent in the background"} + ``` + """ + + def add_task( + self, + func: Annotated[ + Callable[P, Any], + Doc( + """ + The function to call after the response is sent. + + It can be a regular `def` function or an `async def` function. + """ + ), + ], + *args: P.args, + **kwargs: P.kwargs, + ) -> None: + """ + Add a function to be called in the background after the response is sent. + + Read more about it in the + [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/). + """ + return super().add_task(func, *args, **kwargs) diff --git a/venv/lib/python3.11/site-packages/fastapi/cli.py b/venv/lib/python3.11/site-packages/fastapi/cli.py new file mode 100644 index 0000000..8d3301e --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/cli.py @@ -0,0 +1,13 @@ +try: + from fastapi_cli.cli import main as cli_main + +except ImportError: # pragma: no cover + cli_main = None # type: ignore + + +def main() -> None: + if not cli_main: # type: ignore[truthy-function] + message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n' + print(message) + raise RuntimeError(message) # noqa: B904 + cli_main() diff --git a/venv/lib/python3.11/site-packages/fastapi/concurrency.py b/venv/lib/python3.11/site-packages/fastapi/concurrency.py new file mode 100644 index 0000000..3202c70 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/concurrency.py @@ -0,0 +1,39 @@ +from contextlib import asynccontextmanager as asynccontextmanager +from typing import AsyncGenerator, ContextManager, TypeVar + +import anyio.to_thread +from anyio import CapacityLimiter +from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa +from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa +from starlette.concurrency import ( # noqa + run_until_first_complete as run_until_first_complete, +) + +_T = TypeVar("_T") + + +@asynccontextmanager +async def contextmanager_in_threadpool( + cm: ContextManager[_T], +) -> AsyncGenerator[_T, None]: + # blocking __exit__ from running waiting on a free thread + # can create race conditions/deadlocks if the context manager itself + # has its own internal pool (e.g. a database connection pool) + # to avoid this we let __exit__ run without a capacity limit + # since we're creating a new limiter for each call, any non-zero limit + # works (1 is arbitrary) + exit_limiter = CapacityLimiter(1) + try: + yield await run_in_threadpool(cm.__enter__) + except Exception as e: + ok = bool( + await anyio.to_thread.run_sync( + cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter + ) + ) + if not ok: + raise e + else: + await anyio.to_thread.run_sync( + cm.__exit__, None, None, None, limiter=exit_limiter + ) diff --git a/venv/lib/python3.11/site-packages/fastapi/datastructures.py b/venv/lib/python3.11/site-packages/fastapi/datastructures.py new file mode 100644 index 0000000..cf8406b --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/datastructures.py @@ -0,0 +1,204 @@ +from typing import ( + Any, + BinaryIO, + Callable, + Dict, + Iterable, + Optional, + Type, + TypeVar, + cast, +) + +from fastapi._compat import ( + PYDANTIC_V2, + CoreSchema, + GetJsonSchemaHandler, + JsonSchemaValue, + with_info_plain_validator_function, +) +from starlette.datastructures import URL as URL # noqa: F401 +from starlette.datastructures import Address as Address # noqa: F401 +from starlette.datastructures import FormData as FormData # noqa: F401 +from starlette.datastructures import Headers as Headers # noqa: F401 +from starlette.datastructures import QueryParams as QueryParams # noqa: F401 +from starlette.datastructures import State as State # noqa: F401 +from starlette.datastructures import UploadFile as StarletteUploadFile +from typing_extensions import Annotated, Doc + + +class UploadFile(StarletteUploadFile): + """ + A file uploaded in a request. + + Define it as a *path operation function* (or dependency) parameter. + + If you are using a regular `def` function, you can use the `upload_file.file` + attribute to access the raw standard Python file (blocking, not async), useful and + needed for non-async code. + + Read more about it in the + [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/). + + ## Example + + ```python + from typing import Annotated + + from fastapi import FastAPI, File, UploadFile + + app = FastAPI() + + + @app.post("/files/") + async def create_file(file: Annotated[bytes, File()]): + return {"file_size": len(file)} + + + @app.post("/uploadfile/") + async def create_upload_file(file: UploadFile): + return {"filename": file.filename} + ``` + """ + + file: Annotated[ + BinaryIO, + Doc("The standard Python file object (non-async)."), + ] + filename: Annotated[Optional[str], Doc("The original file name.")] + size: Annotated[Optional[int], Doc("The size of the file in bytes.")] + headers: Annotated[Headers, Doc("The headers of the request.")] + content_type: Annotated[ + Optional[str], Doc("The content type of the request, from the headers.") + ] + + async def write( + self, + data: Annotated[ + bytes, + Doc( + """ + The bytes to write to the file. + """ + ), + ], + ) -> None: + """ + Write some bytes to the file. + + You normally wouldn't use this from a file you read in a request. + + To be awaitable, compatible with async, this is run in threadpool. + """ + return await super().write(data) + + async def read( + self, + size: Annotated[ + int, + Doc( + """ + The number of bytes to read from the file. + """ + ), + ] = -1, + ) -> bytes: + """ + Read some bytes from the file. + + To be awaitable, compatible with async, this is run in threadpool. + """ + return await super().read(size) + + async def seek( + self, + offset: Annotated[ + int, + Doc( + """ + The position in bytes to seek to in the file. + """ + ), + ], + ) -> None: + """ + Move to a position in the file. + + Any next read or write will be done from that position. + + To be awaitable, compatible with async, this is run in threadpool. + """ + return await super().seek(offset) + + async def close(self) -> None: + """ + Close the file. + + To be awaitable, compatible with async, this is run in threadpool. + """ + return await super().close() + + @classmethod + def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]: + yield cls.validate + + @classmethod + def validate(cls: Type["UploadFile"], v: Any) -> Any: + if not isinstance(v, StarletteUploadFile): + raise ValueError(f"Expected UploadFile, received: {type(v)}") + return v + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> "UploadFile": + if not isinstance(__input_value, StarletteUploadFile): + raise ValueError(f"Expected UploadFile, received: {type(__input_value)}") + return cast(UploadFile, __input_value) + + if not PYDANTIC_V2: + + @classmethod + def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: + field_schema.update({"type": "string", "format": "binary"}) + + @classmethod + def __get_pydantic_json_schema__( + cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler + ) -> JsonSchemaValue: + return {"type": "string", "format": "binary"} + + @classmethod + def __get_pydantic_core_schema__( + cls, source: Type[Any], handler: Callable[[Any], CoreSchema] + ) -> CoreSchema: + return with_info_plain_validator_function(cls._validate) + + +class DefaultPlaceholder: + """ + You shouldn't use this class directly. + + It's used internally to recognize when a default value has been overwritten, even + if the overridden default value was truthy. + """ + + def __init__(self, value: Any): + self.value = value + + def __bool__(self) -> bool: + return bool(self.value) + + def __eq__(self, o: object) -> bool: + return isinstance(o, DefaultPlaceholder) and o.value == self.value + + +DefaultType = TypeVar("DefaultType") + + +def Default(value: DefaultType) -> DefaultType: + """ + You shouldn't use this function directly. + + It's used internally to recognize when a default value has been overwritten, even + if the overridden default value was truthy. + """ + return DefaultPlaceholder(value) # type: ignore diff --git a/venv/lib/python3.11/site-packages/fastapi/dependencies/__init__.py b/venv/lib/python3.11/site-packages/fastapi/dependencies/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87e9e9ae26c71f1a133cff736c9c51b704816fd8 GIT binary patch literal 199 zcmZ3^%ge<81aZ$^r-SInAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnuPFVp#3KFj z@^byu-2AM})Uy1X(vr;lJpHoNyfXcq%q0DS%94!yJYzjWL;d2+l2qM-#N_P6^weVg zw8Y|)#DYxyl+=RMyp+_uJoe0*kJW=VX!UP0wA4x8Nkl+v73yCPPgRUpR{^8<+w Q%#4hT9~fXn5i?K>0E-qh#Q*>R literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/models.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/models.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ddd21e5a2dc7095b8ade7651922abbd17de147d1 GIT binary patch literal 3383 zcmb7GO>7&-6`m!B6n`aK6!m9Ywyd9ul119FZ1vz)QtT>eohY$nSHS}9VzoPxXf1b{ z*`-~jLBWF$I^>{30qfuc5u~n*B!CYspkt3Y?gD!t_7osMfFcMW!#U-Y_m)2*O-F5q z!*Acr`{vExn>X|KWHLq|{qfuHw!R4w@(mUm3CezY`6+xJ6P2ifMhb!`6ar#Ez;Zwf z7N|%IAu&`4i{V0-*j0##kwR3A`ud<2E5yaPFHJ*8>`|j@Boq4&w#@{*s482sqRFP|g*Nj{Q!`;NxTNoTk(;un z$r~E;=sS7S@*?jQt-PVjnipAPAC{P|FfVksRMc2T@M7;8D$|zz_JWsKV@iqVt=%_e zlPS$Xf)K11UM_<0m@py=DiH(s2n#Z*3OAru4TvEYW?d{YR3{U1ECDN6W5Fb-mumF1 z3PZ|sR$#j2^+2b7_mZh>L)D5GHWj1D%uLjaNRloWm?U{INh%m>NkcgyNgtMEt)}4# z=-2C!Bw5!DOU6l?lEhCzEsr2XQ6Drd{txmJMDpVYxd$@OJ$(2u#|p;%JbPehC2W>^ z!1M<>Ex(Z~?poW1el>gLO3ut%Y_=#XJMtDYbDOeh$;Et5Wksf|u&8;cgmE#=%ocZf zH};2s9h>t2<(A*q=~0_vcIaqza=N^{_xAn=2g+an;3mdwIt|(J5d=Qau++96O}G6P z9IJId0{)JCAv_hp&EQ{4wVi3%jffh+-S`=H6!)=>?eE>suwxx;dV=kE2Rn2EJJG=o zpTJJCu-fW#5w+_Cb~o7WX`5vP*=kfg#ZI%{HchOqNr9$MjkEM-;8=ewv51xWrnjy+3z~524BKXq@>zZ2IW_|GN!Qz) z@37X78uSTu;ETam{Otl81^!7ZHOhL`cqQ+it(rYQPI-L~*@kH-JFKmCc-yjyl49sOQ!vo9 zwn%Yi79nKShgCCkW&;Aw7B@<|Dp|6*W45*!ZVs*%CR=r_u@pn-T`yV!(~1m{)uXsl z%dmztujef<>eos;Y}X5OW|g?EG$RLWF@`XV|1bXn@R)o|?!&j1tj4_nMXM2$Q0}S| z-~)WxC>4b*((WlIl{Nz(6RBxcC2(^HE157K2XkJ?!Yd4J2!mTpg|N;nJ_8D#1Hh@7 zOxrYZ9vAo^Hb_cR(SS|DDNE8v15IDbwkgoKIR{WC)!~sRnZMop^7_BVo~!Ql-`UsS z|7yc|S{iJ&jetxvh1o&lWzmgf_r{T+c5mE@a4j$Fu zR_151jH|@s2z?0W5JnKrBV0fjMYxFIUnyfK`IlK5B^)ddBj7Ue34}?6Um#2&WDuqi z{MESxl1DcTL*uhpiL1r&dBm?H^dtCJ4z3v=ZUA;}-iEuT?HU`;RDN?fZjUcG;|uQi zLizT7-~N5~G~8?pkR7^EotUoNJDjs87M+PjcVe;p&i?rRM{e&$n=V3j=wfwpros+y z*^^7o3fHtj!%R8mipHU;^TLoZdQvo;+(n5tZT0yL1b4$W3CLq8*x$g|XEzyx{D zp>tr|rUM6qm9Z!1j%{AKX4CVP!DnNiK_$r79D42b&1Z7u_uyfnLQi=&J!R7zWQXRe z{ln$o?pZb+hV0Pc*G_Et_P?2Z=lAyVy0g6QF0Vt25*XXAn9puj{^X8acGFj$Upq`4 zDu;vrT(Hw`x;-~-x(?Z)>qk@w-4l+;Nm%nUbg`ApDKFl9&oYx^SgDsvMd z_C4J{H2x95_nhy$UQhiwmW9|_fZ*mIDlgrrZN$m!2E1$iXJYL%`R?8B@;^py)Lxgr z=Dz~-7(dMK0gi%#AXLee{kmKwOZNYhzb2D*d#;kK-JXxaBoIFe1caF*(g`oH?gxYy fLEt?asxf1Jn|=Y8{`L66um8cvX46-x{?7aaxt>Wq literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/dependencies/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94e51cf35795eac4f3785b40e64b3289001540df GIT binary patch literal 41939 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

    J z?@1F5c#eqK&x%0VNuq#NFqag0|6R8>^3u5 zCt{dBTL`ogXd}>0po2gsfi40xJu`)h@(mfi^w~#%n56lV-ob(LQF?arM$ut7fO^Aq z>pVMsKS<$dg2~sH3ZOn^G{8uOlzf5j2zhgtyv@vBy$T82QL+q{EK4_FAn{b3UErRt z-rzPnF`vFRBH!%3or1S-^n#n)$ERbZ>pRBh`5ATzJoFCX3Zsd+=>h1M!8JU@lxCL| z<*jqKViO=VCz*Ij-c$M_&YGqQ~=- zbc?NMX9ygmAXVicMN%#$tH?Y|u70(vtll6cA0<=eP`TP9#UG_WKDqZ2 zQ#qbYfmTlO$0)ty1WpjRNZ>qy%LMKb_>{l|fjEJ2fV}lEX-_yEzeU;vW@l74l>R#T z`F#R^K;X9t{D44`z&|DMX9WI`z>f)hLEvu){DJ`XX5>R%>|Bz}4`EDxCeU)2Tp6RJ znoNXnnKZaO|6D=@zp(B_m%|+$`}sw<;^k8R64)DzS)DG&xfj`Aj@u?|_U5=|VY4^K zwFug`pm*!^xIpFa83;p> zfjhSG-Pk{J+BA?}j@vD4_U5?#g7(dEhlI`E9M>dh-yGK=Xx|+7te|~!+^C>^3wkpZ z`0onboNkA}ZQuCjxNbrF=C~d~`{uZP!q#uWtT%N)T1(edaGGROYavjhI{~$;8{jiK zu5YN|aFc992|$H6&H};)C(#19_uN8eE9Y<*Y-F-?p{C{7%IMu`DcCIsb#i7;!Bq-h zj;YXU)V-)%Gye!j-pKUHr2PBowEVjXtl{dLbG?HFSECMGy%Kor@*^WA`oxx3?XrJ) za=8W?UketplJiC;JBM3+M(^|&9Q5VXQ&3S0@~JT(OaeV93ab-_X=>??+r zV#_<(twXYRJ0r!MF4iW0A9>hM`E$u(c%#|Qu)*aI=-=aQv zOt*Srtw-wLCx2`Lt6aMJUUb`%9JH||vAZ*lyR?btagw~Ec@IRP* zQ1c^X0-v9x*iR*JTXox4uC1ol4zIp0b?(HqR=VvE5CMKFL6h9DP{C7h4eNpht^^+2 zT?G?;m|5d382yg7fUV4&X! zj;PV^u0!nivB{NLL!910_zl~68^Pyf2X(KyFccH&9dFmlKAn?#-DMpc zLCi$mHBhj~W~?SW1)FTfHGDM%hiu01sVcZ+Gh~PmK|%ZTtjVPtSOISyKM&A#@$*TV z{ZxXmSvR&~UG=X{uGUE55$X|RYw(JnN>F9gjcUB&o4n$u61a`JG1bT*=drZ_`>6zO zi*Ar^+nQV+UAiW@nhOT9=-w{>9y#%;|I^7&Ykqo`eLpsV9}jox;%X3JHE+U<0a?^d zAr2J79w&+cl?Gs5Yq%YIa(fQs+PZS1J96hQ7kqE%2)mWxV^`JEj^&erzXKY<3MS@& z#bIs1!i=oXZCeg3Pp*tEU%T71S|ijBL*uMuA1&CJ4?9=gENhu6IGBZ#^HeXrF1f=6 z7yEW|?R~3E}ehZmfbIz>Ixi6{mkqm*Ua None: + self.cache_key = (self.call, tuple(sorted(set(self.security_scopes or [])))) diff --git a/venv/lib/python3.11/site-packages/fastapi/dependencies/utils.py b/venv/lib/python3.11/site-packages/fastapi/dependencies/utils.py new file mode 100644 index 0000000..84dfa4d --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/dependencies/utils.py @@ -0,0 +1,980 @@ +import inspect +from contextlib import AsyncExitStack, contextmanager +from copy import copy, deepcopy +from dataclasses import dataclass +from typing import ( + Any, + Callable, + Coroutine, + Dict, + ForwardRef, + List, + Mapping, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +import anyio +from fastapi import params +from fastapi._compat import ( + PYDANTIC_V2, + ErrorWrapper, + ModelField, + RequiredParam, + Undefined, + _regenerate_error_with_loc, + copy_field_info, + create_body_model, + evaluate_forwardref, + field_annotation_is_scalar, + get_annotation_from_field_info, + get_cached_model_fields, + get_missing_field_error, + is_bytes_field, + is_bytes_sequence_field, + is_scalar_field, + is_scalar_sequence_field, + is_sequence_field, + is_uploadfile_or_nonable_uploadfile_annotation, + is_uploadfile_sequence_annotation, + lenient_issubclass, + sequence_types, + serialize_sequence_value, + value_is_sequence, +) +from fastapi.background import BackgroundTasks +from fastapi.concurrency import ( + asynccontextmanager, + contextmanager_in_threadpool, +) +from fastapi.dependencies.models import Dependant, SecurityRequirement +from fastapi.logger import logger +from fastapi.security.base import SecurityBase +from fastapi.security.oauth2 import OAuth2, SecurityScopes +from fastapi.security.open_id_connect_url import OpenIdConnect +from fastapi.utils import create_model_field, get_path_param_names +from pydantic import BaseModel +from pydantic.fields import FieldInfo +from starlette.background import BackgroundTasks as StarletteBackgroundTasks +from starlette.concurrency import run_in_threadpool +from starlette.datastructures import ( + FormData, + Headers, + ImmutableMultiDict, + QueryParams, + UploadFile, +) +from starlette.requests import HTTPConnection, Request +from starlette.responses import Response +from starlette.websockets import WebSocket +from typing_extensions import Annotated, get_args, get_origin + +multipart_not_installed_error = ( + 'Form data requires "python-multipart" to be installed. \n' + 'You can install "python-multipart" with: \n\n' + "pip install python-multipart\n" +) +multipart_incorrect_install_error = ( + 'Form data requires "python-multipart" to be installed. ' + 'It seems you installed "multipart" instead. \n' + 'You can remove "multipart" with: \n\n' + "pip uninstall multipart\n\n" + 'And then install "python-multipart" with: \n\n' + "pip install python-multipart\n" +) + + +def ensure_multipart_is_installed() -> None: + try: + from python_multipart import __version__ + + # Import an attribute that can be mocked/deleted in testing + assert __version__ > "0.0.12" + except (ImportError, AssertionError): + try: + # __version__ is available in both multiparts, and can be mocked + from multipart import __version__ # type: ignore[no-redef,import-untyped] + + assert __version__ + try: + # parse_options_header is only available in the right multipart + from multipart.multipart import ( # type: ignore[import-untyped] + parse_options_header, + ) + + assert parse_options_header + except ImportError: + logger.error(multipart_incorrect_install_error) + raise RuntimeError(multipart_incorrect_install_error) from None + except ImportError: + logger.error(multipart_not_installed_error) + raise RuntimeError(multipart_not_installed_error) from None + + +def get_param_sub_dependant( + *, + param_name: str, + depends: params.Depends, + path: str, + security_scopes: Optional[List[str]] = None, +) -> Dependant: + assert depends.dependency + return get_sub_dependant( + depends=depends, + dependency=depends.dependency, + path=path, + name=param_name, + security_scopes=security_scopes, + ) + + +def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant: + assert callable(depends.dependency), ( + "A parameter-less dependency must have a callable dependency" + ) + return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path) + + +def get_sub_dependant( + *, + depends: params.Depends, + dependency: Callable[..., Any], + path: str, + name: Optional[str] = None, + security_scopes: Optional[List[str]] = None, +) -> Dependant: + security_requirement = None + security_scopes = security_scopes or [] + if isinstance(depends, params.Security): + dependency_scopes = depends.scopes + security_scopes.extend(dependency_scopes) + if isinstance(dependency, SecurityBase): + use_scopes: List[str] = [] + if isinstance(dependency, (OAuth2, OpenIdConnect)): + use_scopes = security_scopes + security_requirement = SecurityRequirement( + security_scheme=dependency, scopes=use_scopes + ) + sub_dependant = get_dependant( + path=path, + call=dependency, + name=name, + security_scopes=security_scopes, + use_cache=depends.use_cache, + ) + if security_requirement: + sub_dependant.security_requirements.append(security_requirement) + return sub_dependant + + +CacheKey = Tuple[Optional[Callable[..., Any]], Tuple[str, ...]] + + +def get_flat_dependant( + dependant: Dependant, + *, + skip_repeats: bool = False, + visited: Optional[List[CacheKey]] = None, +) -> Dependant: + if visited is None: + visited = [] + visited.append(dependant.cache_key) + + flat_dependant = Dependant( + path_params=dependant.path_params.copy(), + query_params=dependant.query_params.copy(), + header_params=dependant.header_params.copy(), + cookie_params=dependant.cookie_params.copy(), + body_params=dependant.body_params.copy(), + security_requirements=dependant.security_requirements.copy(), + use_cache=dependant.use_cache, + path=dependant.path, + ) + for sub_dependant in dependant.dependencies: + if skip_repeats and sub_dependant.cache_key in visited: + continue + flat_sub = get_flat_dependant( + sub_dependant, skip_repeats=skip_repeats, visited=visited + ) + flat_dependant.path_params.extend(flat_sub.path_params) + flat_dependant.query_params.extend(flat_sub.query_params) + flat_dependant.header_params.extend(flat_sub.header_params) + flat_dependant.cookie_params.extend(flat_sub.cookie_params) + flat_dependant.body_params.extend(flat_sub.body_params) + flat_dependant.security_requirements.extend(flat_sub.security_requirements) + return flat_dependant + + +def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]: + if not fields: + return fields + first_field = fields[0] + if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel): + fields_to_extract = get_cached_model_fields(first_field.type_) + return fields_to_extract + return fields + + +def get_flat_params(dependant: Dependant) -> List[ModelField]: + flat_dependant = get_flat_dependant(dependant, skip_repeats=True) + path_params = _get_flat_fields_from_params(flat_dependant.path_params) + query_params = _get_flat_fields_from_params(flat_dependant.query_params) + header_params = _get_flat_fields_from_params(flat_dependant.header_params) + cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params) + return path_params + query_params + header_params + cookie_params + + +def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature: + signature = inspect.signature(call) + globalns = getattr(call, "__globals__", {}) + typed_params = [ + inspect.Parameter( + name=param.name, + kind=param.kind, + default=param.default, + annotation=get_typed_annotation(param.annotation, globalns), + ) + for param in signature.parameters.values() + ] + typed_signature = inspect.Signature(typed_params) + return typed_signature + + +def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any: + if isinstance(annotation, str): + annotation = ForwardRef(annotation) + annotation = evaluate_forwardref(annotation, globalns, globalns) + return annotation + + +def get_typed_return_annotation(call: Callable[..., Any]) -> Any: + signature = inspect.signature(call) + annotation = signature.return_annotation + + if annotation is inspect.Signature.empty: + return None + + globalns = getattr(call, "__globals__", {}) + return get_typed_annotation(annotation, globalns) + + +def get_dependant( + *, + path: str, + call: Callable[..., Any], + name: Optional[str] = None, + security_scopes: Optional[List[str]] = None, + use_cache: bool = True, +) -> Dependant: + path_param_names = get_path_param_names(path) + endpoint_signature = get_typed_signature(call) + signature_params = endpoint_signature.parameters + dependant = Dependant( + call=call, + name=name, + path=path, + security_scopes=security_scopes, + use_cache=use_cache, + ) + for param_name, param in signature_params.items(): + is_path_param = param_name in path_param_names + param_details = analyze_param( + param_name=param_name, + annotation=param.annotation, + value=param.default, + is_path_param=is_path_param, + ) + if param_details.depends is not None: + sub_dependant = get_param_sub_dependant( + param_name=param_name, + depends=param_details.depends, + path=path, + security_scopes=security_scopes, + ) + dependant.dependencies.append(sub_dependant) + continue + if add_non_field_param_to_dependency( + param_name=param_name, + type_annotation=param_details.type_annotation, + dependant=dependant, + ): + assert param_details.field is None, ( + f"Cannot specify multiple FastAPI annotations for {param_name!r}" + ) + continue + assert param_details.field is not None + if isinstance(param_details.field.field_info, params.Body): + dependant.body_params.append(param_details.field) + else: + add_param_to_fields(field=param_details.field, dependant=dependant) + return dependant + + +def add_non_field_param_to_dependency( + *, param_name: str, type_annotation: Any, dependant: Dependant +) -> Optional[bool]: + if lenient_issubclass(type_annotation, Request): + dependant.request_param_name = param_name + return True + elif lenient_issubclass(type_annotation, WebSocket): + dependant.websocket_param_name = param_name + return True + elif lenient_issubclass(type_annotation, HTTPConnection): + dependant.http_connection_param_name = param_name + return True + elif lenient_issubclass(type_annotation, Response): + dependant.response_param_name = param_name + return True + elif lenient_issubclass(type_annotation, StarletteBackgroundTasks): + dependant.background_tasks_param_name = param_name + return True + elif lenient_issubclass(type_annotation, SecurityScopes): + dependant.security_scopes_param_name = param_name + return True + return None + + +@dataclass +class ParamDetails: + type_annotation: Any + depends: Optional[params.Depends] + field: Optional[ModelField] + + +def analyze_param( + *, + param_name: str, + annotation: Any, + value: Any, + is_path_param: bool, +) -> ParamDetails: + field_info = None + depends = None + type_annotation: Any = Any + use_annotation: Any = Any + if annotation is not inspect.Signature.empty: + use_annotation = annotation + type_annotation = annotation + # Extract Annotated info + if get_origin(use_annotation) is Annotated: + annotated_args = get_args(annotation) + type_annotation = annotated_args[0] + fastapi_annotations = [ + arg + for arg in annotated_args[1:] + if isinstance(arg, (FieldInfo, params.Depends)) + ] + fastapi_specific_annotations = [ + arg + for arg in fastapi_annotations + if isinstance(arg, (params.Param, params.Body, params.Depends)) + ] + if fastapi_specific_annotations: + fastapi_annotation: Union[FieldInfo, params.Depends, None] = ( + fastapi_specific_annotations[-1] + ) + else: + fastapi_annotation = None + # Set default for Annotated FieldInfo + if isinstance(fastapi_annotation, FieldInfo): + # Copy `field_info` because we mutate `field_info.default` below. + field_info = copy_field_info( + field_info=fastapi_annotation, annotation=use_annotation + ) + assert ( + field_info.default is Undefined or field_info.default is RequiredParam + ), ( + f"`{field_info.__class__.__name__}` default value cannot be set in" + f" `Annotated` for {param_name!r}. Set the default value with `=` instead." + ) + if value is not inspect.Signature.empty: + assert not is_path_param, "Path parameters cannot have default values" + field_info.default = value + else: + field_info.default = RequiredParam + # Get Annotated Depends + elif isinstance(fastapi_annotation, params.Depends): + depends = fastapi_annotation + # Get Depends from default value + if isinstance(value, params.Depends): + assert depends is None, ( + "Cannot specify `Depends` in `Annotated` and default value" + f" together for {param_name!r}" + ) + assert field_info is None, ( + "Cannot specify a FastAPI annotation in `Annotated` and `Depends` as a" + f" default value together for {param_name!r}" + ) + depends = value + # Get FieldInfo from default value + elif isinstance(value, FieldInfo): + assert field_info is None, ( + "Cannot specify FastAPI annotations in `Annotated` and default value" + f" together for {param_name!r}" + ) + field_info = value + if PYDANTIC_V2: + field_info.annotation = type_annotation + + # Get Depends from type annotation + if depends is not None and depends.dependency is None: + # Copy `depends` before mutating it + depends = copy(depends) + depends.dependency = type_annotation + + # Handle non-param type annotations like Request + if lenient_issubclass( + type_annotation, + ( + Request, + WebSocket, + HTTPConnection, + Response, + StarletteBackgroundTasks, + SecurityScopes, + ), + ): + assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}" + assert field_info is None, ( + f"Cannot specify FastAPI annotation for type {type_annotation!r}" + ) + # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value + elif field_info is None and depends is None: + default_value = value if value is not inspect.Signature.empty else RequiredParam + if is_path_param: + # We might check here that `default_value is RequiredParam`, but the fact is that the same + # parameter might sometimes be a path parameter and sometimes not. See + # `tests/test_infer_param_optionality.py` for an example. + field_info = params.Path(annotation=use_annotation) + elif is_uploadfile_or_nonable_uploadfile_annotation( + type_annotation + ) or is_uploadfile_sequence_annotation(type_annotation): + field_info = params.File(annotation=use_annotation, default=default_value) + elif not field_annotation_is_scalar(annotation=type_annotation): + field_info = params.Body(annotation=use_annotation, default=default_value) + else: + field_info = params.Query(annotation=use_annotation, default=default_value) + + field = None + # It's a field_info, not a dependency + if field_info is not None: + # Handle field_info.in_ + if is_path_param: + assert isinstance(field_info, params.Path), ( + f"Cannot use `{field_info.__class__.__name__}` for path param" + f" {param_name!r}" + ) + elif ( + isinstance(field_info, params.Param) + and getattr(field_info, "in_", None) is None + ): + field_info.in_ = params.ParamTypes.query + use_annotation_from_field_info = get_annotation_from_field_info( + use_annotation, + field_info, + param_name, + ) + if isinstance(field_info, params.Form): + ensure_multipart_is_installed() + if not field_info.alias and getattr(field_info, "convert_underscores", None): + alias = param_name.replace("_", "-") + else: + alias = field_info.alias or param_name + field_info.alias = alias + field = create_model_field( + name=param_name, + type_=use_annotation_from_field_info, + default=field_info.default, + alias=alias, + required=field_info.default in (RequiredParam, Undefined), + field_info=field_info, + ) + if is_path_param: + assert is_scalar_field(field=field), ( + "Path params must be of one of the supported types" + ) + elif isinstance(field_info, params.Query): + assert ( + is_scalar_field(field) + or is_scalar_sequence_field(field) + or ( + lenient_issubclass(field.type_, BaseModel) + # For Pydantic v1 + and getattr(field, "shape", 1) == 1 + ) + ) + + return ParamDetails(type_annotation=type_annotation, depends=depends, field=field) + + +def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None: + field_info = field.field_info + field_info_in = getattr(field_info, "in_", None) + if field_info_in == params.ParamTypes.path: + dependant.path_params.append(field) + elif field_info_in == params.ParamTypes.query: + dependant.query_params.append(field) + elif field_info_in == params.ParamTypes.header: + dependant.header_params.append(field) + else: + assert field_info_in == params.ParamTypes.cookie, ( + f"non-body parameters must be in path, query, header or cookie: {field.name}" + ) + dependant.cookie_params.append(field) + + +def is_coroutine_callable(call: Callable[..., Any]) -> bool: + if inspect.isroutine(call): + return inspect.iscoroutinefunction(call) + if inspect.isclass(call): + return False + dunder_call = getattr(call, "__call__", None) # noqa: B004 + return inspect.iscoroutinefunction(dunder_call) + + +def is_async_gen_callable(call: Callable[..., Any]) -> bool: + if inspect.isasyncgenfunction(call): + return True + dunder_call = getattr(call, "__call__", None) # noqa: B004 + return inspect.isasyncgenfunction(dunder_call) + + +def is_gen_callable(call: Callable[..., Any]) -> bool: + if inspect.isgeneratorfunction(call): + return True + dunder_call = getattr(call, "__call__", None) # noqa: B004 + return inspect.isgeneratorfunction(dunder_call) + + +async def solve_generator( + *, call: Callable[..., Any], stack: AsyncExitStack, sub_values: Dict[str, Any] +) -> Any: + if is_gen_callable(call): + cm = contextmanager_in_threadpool(contextmanager(call)(**sub_values)) + elif is_async_gen_callable(call): + cm = asynccontextmanager(call)(**sub_values) + return await stack.enter_async_context(cm) + + +@dataclass +class SolvedDependency: + values: Dict[str, Any] + errors: List[Any] + background_tasks: Optional[StarletteBackgroundTasks] + response: Response + dependency_cache: Dict[Tuple[Callable[..., Any], Tuple[str]], Any] + + +async def solve_dependencies( + *, + request: Union[Request, WebSocket], + dependant: Dependant, + body: Optional[Union[Dict[str, Any], FormData]] = None, + background_tasks: Optional[StarletteBackgroundTasks] = None, + response: Optional[Response] = None, + dependency_overrides_provider: Optional[Any] = None, + dependency_cache: Optional[Dict[Tuple[Callable[..., Any], Tuple[str]], Any]] = None, + async_exit_stack: AsyncExitStack, + embed_body_fields: bool, +) -> SolvedDependency: + values: Dict[str, Any] = {} + errors: List[Any] = [] + if response is None: + response = Response() + del response.headers["content-length"] + response.status_code = None # type: ignore + dependency_cache = dependency_cache or {} + sub_dependant: Dependant + for sub_dependant in dependant.dependencies: + sub_dependant.call = cast(Callable[..., Any], sub_dependant.call) + sub_dependant.cache_key = cast( + Tuple[Callable[..., Any], Tuple[str]], sub_dependant.cache_key + ) + call = sub_dependant.call + use_sub_dependant = sub_dependant + if ( + dependency_overrides_provider + and dependency_overrides_provider.dependency_overrides + ): + original_call = sub_dependant.call + call = getattr( + dependency_overrides_provider, "dependency_overrides", {} + ).get(original_call, original_call) + use_path: str = sub_dependant.path # type: ignore + use_sub_dependant = get_dependant( + path=use_path, + call=call, + name=sub_dependant.name, + security_scopes=sub_dependant.security_scopes, + ) + + solved_result = await solve_dependencies( + request=request, + dependant=use_sub_dependant, + body=body, + background_tasks=background_tasks, + response=response, + dependency_overrides_provider=dependency_overrides_provider, + dependency_cache=dependency_cache, + async_exit_stack=async_exit_stack, + embed_body_fields=embed_body_fields, + ) + background_tasks = solved_result.background_tasks + dependency_cache.update(solved_result.dependency_cache) + if solved_result.errors: + errors.extend(solved_result.errors) + continue + if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache: + solved = dependency_cache[sub_dependant.cache_key] + elif is_gen_callable(call) or is_async_gen_callable(call): + solved = await solve_generator( + call=call, stack=async_exit_stack, sub_values=solved_result.values + ) + elif is_coroutine_callable(call): + solved = await call(**solved_result.values) + else: + solved = await run_in_threadpool(call, **solved_result.values) + if sub_dependant.name is not None: + values[sub_dependant.name] = solved + if sub_dependant.cache_key not in dependency_cache: + dependency_cache[sub_dependant.cache_key] = solved + path_values, path_errors = request_params_to_args( + dependant.path_params, request.path_params + ) + query_values, query_errors = request_params_to_args( + dependant.query_params, request.query_params + ) + header_values, header_errors = request_params_to_args( + dependant.header_params, request.headers + ) + cookie_values, cookie_errors = request_params_to_args( + dependant.cookie_params, request.cookies + ) + values.update(path_values) + values.update(query_values) + values.update(header_values) + values.update(cookie_values) + errors += path_errors + query_errors + header_errors + cookie_errors + if dependant.body_params: + ( + body_values, + body_errors, + ) = await request_body_to_args( # body_params checked above + body_fields=dependant.body_params, + received_body=body, + embed_body_fields=embed_body_fields, + ) + values.update(body_values) + errors.extend(body_errors) + if dependant.http_connection_param_name: + values[dependant.http_connection_param_name] = request + if dependant.request_param_name and isinstance(request, Request): + values[dependant.request_param_name] = request + elif dependant.websocket_param_name and isinstance(request, WebSocket): + values[dependant.websocket_param_name] = request + if dependant.background_tasks_param_name: + if background_tasks is None: + background_tasks = BackgroundTasks() + values[dependant.background_tasks_param_name] = background_tasks + if dependant.response_param_name: + values[dependant.response_param_name] = response + if dependant.security_scopes_param_name: + values[dependant.security_scopes_param_name] = SecurityScopes( + scopes=dependant.security_scopes + ) + return SolvedDependency( + values=values, + errors=errors, + background_tasks=background_tasks, + response=response, + dependency_cache=dependency_cache, + ) + + +def _validate_value_with_model_field( + *, field: ModelField, value: Any, values: Dict[str, Any], loc: Tuple[str, ...] +) -> Tuple[Any, List[Any]]: + if value is None: + if field.required: + return None, [get_missing_field_error(loc=loc)] + else: + return deepcopy(field.default), [] + v_, errors_ = field.validate(value, values, loc=loc) + if isinstance(errors_, ErrorWrapper): + return None, [errors_] + elif isinstance(errors_, list): + new_errors = _regenerate_error_with_loc(errors=errors_, loc_prefix=()) + return None, new_errors + else: + return v_, [] + + +def _get_multidict_value( + field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None +) -> Any: + alias = alias or field.alias + if is_sequence_field(field) and isinstance(values, (ImmutableMultiDict, Headers)): + value = values.getlist(alias) + else: + value = values.get(alias, None) + if ( + value is None + or ( + isinstance(field.field_info, params.Form) + and isinstance(value, str) # For type checks + and value == "" + ) + or (is_sequence_field(field) and len(value) == 0) + ): + if field.required: + return + else: + return deepcopy(field.default) + return value + + +def request_params_to_args( + fields: Sequence[ModelField], + received_params: Union[Mapping[str, Any], QueryParams, Headers], +) -> Tuple[Dict[str, Any], List[Any]]: + values: Dict[str, Any] = {} + errors: List[Dict[str, Any]] = [] + + if not fields: + return values, errors + + first_field = fields[0] + fields_to_extract = fields + single_not_embedded_field = False + default_convert_underscores = True + if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel): + fields_to_extract = get_cached_model_fields(first_field.type_) + single_not_embedded_field = True + # If headers are in a Pydantic model, the way to disable convert_underscores + # would be with Header(convert_underscores=False) at the Pydantic model level + default_convert_underscores = getattr( + first_field.field_info, "convert_underscores", True + ) + + params_to_process: Dict[str, Any] = {} + + processed_keys = set() + + for field in fields_to_extract: + alias = None + if isinstance(received_params, Headers): + # Handle fields extracted from a Pydantic Model for a header, each field + # doesn't have a FieldInfo of type Header with the default convert_underscores=True + convert_underscores = getattr( + field.field_info, "convert_underscores", default_convert_underscores + ) + if convert_underscores: + alias = ( + field.alias + if field.alias != field.name + else field.name.replace("_", "-") + ) + value = _get_multidict_value(field, received_params, alias=alias) + if value is not None: + params_to_process[field.name] = value + processed_keys.add(alias or field.alias) + processed_keys.add(field.name) + + for key, value in received_params.items(): + if key not in processed_keys: + params_to_process[key] = value + + if single_not_embedded_field: + field_info = first_field.field_info + assert isinstance(field_info, params.Param), ( + "Params must be subclasses of Param" + ) + loc: Tuple[str, ...] = (field_info.in_.value,) + v_, errors_ = _validate_value_with_model_field( + field=first_field, value=params_to_process, values=values, loc=loc + ) + return {first_field.name: v_}, errors_ + + for field in fields: + value = _get_multidict_value(field, received_params) + field_info = field.field_info + assert isinstance(field_info, params.Param), ( + "Params must be subclasses of Param" + ) + loc = (field_info.in_.value, field.alias) + v_, errors_ = _validate_value_with_model_field( + field=field, value=value, values=values, loc=loc + ) + if errors_: + errors.extend(errors_) + else: + values[field.name] = v_ + return values, errors + + +def _should_embed_body_fields(fields: List[ModelField]) -> bool: + if not fields: + return False + # More than one dependency could have the same field, it would show up as multiple + # fields but it's the same one, so count them by name + body_param_names_set = {field.name for field in fields} + # A top level field has to be a single field, not multiple + if len(body_param_names_set) > 1: + return True + first_field = fields[0] + # If it explicitly specifies it is embedded, it has to be embedded + if getattr(first_field.field_info, "embed", None): + return True + # If it's a Form (or File) field, it has to be a BaseModel to be top level + # otherwise it has to be embedded, so that the key value pair can be extracted + if isinstance(first_field.field_info, params.Form) and not lenient_issubclass( + first_field.type_, BaseModel + ): + return True + return False + + +async def _extract_form_body( + body_fields: List[ModelField], + received_body: FormData, +) -> Dict[str, Any]: + values = {} + first_field = body_fields[0] + first_field_info = first_field.field_info + + for field in body_fields: + value = _get_multidict_value(field, received_body) + if ( + isinstance(first_field_info, params.File) + and is_bytes_field(field) + and isinstance(value, UploadFile) + ): + value = await value.read() + elif ( + is_bytes_sequence_field(field) + and isinstance(first_field_info, params.File) + and value_is_sequence(value) + ): + # For types + assert isinstance(value, sequence_types) # type: ignore[arg-type] + results: List[Union[bytes, str]] = [] + + async def process_fn( + fn: Callable[[], Coroutine[Any, Any, Any]], + ) -> None: + result = await fn() + results.append(result) # noqa: B023 + + async with anyio.create_task_group() as tg: + for sub_value in value: + tg.start_soon(process_fn, sub_value.read) + value = serialize_sequence_value(field=field, value=results) + if value is not None: + values[field.alias] = value + for key, value in received_body.items(): + if key not in values: + values[key] = value + return values + + +async def request_body_to_args( + body_fields: List[ModelField], + received_body: Optional[Union[Dict[str, Any], FormData]], + embed_body_fields: bool, +) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]: + values: Dict[str, Any] = {} + errors: List[Dict[str, Any]] = [] + assert body_fields, "request_body_to_args() should be called with fields" + single_not_embedded_field = len(body_fields) == 1 and not embed_body_fields + first_field = body_fields[0] + body_to_process = received_body + + fields_to_extract: List[ModelField] = body_fields + + if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel): + fields_to_extract = get_cached_model_fields(first_field.type_) + + if isinstance(received_body, FormData): + body_to_process = await _extract_form_body(fields_to_extract, received_body) + + if single_not_embedded_field: + loc: Tuple[str, ...] = ("body",) + v_, errors_ = _validate_value_with_model_field( + field=first_field, value=body_to_process, values=values, loc=loc + ) + return {first_field.name: v_}, errors_ + for field in body_fields: + loc = ("body", field.alias) + value: Optional[Any] = None + if body_to_process is not None: + try: + value = body_to_process.get(field.alias) + # If the received body is a list, not a dict + except AttributeError: + errors.append(get_missing_field_error(loc)) + continue + v_, errors_ = _validate_value_with_model_field( + field=field, value=value, values=values, loc=loc + ) + if errors_: + errors.extend(errors_) + else: + values[field.name] = v_ + return values, errors + + +def get_body_field( + *, flat_dependant: Dependant, name: str, embed_body_fields: bool +) -> Optional[ModelField]: + """ + Get a ModelField representing the request body for a path operation, combining + all body parameters into a single field if necessary. + + Used to check if it's form data (with `isinstance(body_field, params.Form)`) + or JSON and to generate the JSON Schema for a request body. + + This is **not** used to validate/parse the request body, that's done with each + individual body parameter. + """ + if not flat_dependant.body_params: + return None + first_param = flat_dependant.body_params[0] + if not embed_body_fields: + return first_param + model_name = "Body_" + name + BodyModel = create_body_model( + fields=flat_dependant.body_params, model_name=model_name + ) + required = any(True for f in flat_dependant.body_params if f.required) + BodyFieldInfo_kwargs: Dict[str, Any] = { + "annotation": BodyModel, + "alias": "body", + } + if not required: + BodyFieldInfo_kwargs["default"] = None + if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params): + BodyFieldInfo: Type[params.Body] = params.File + elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params): + BodyFieldInfo = params.Form + else: + BodyFieldInfo = params.Body + + body_param_media_types = [ + f.field_info.media_type + for f in flat_dependant.body_params + if isinstance(f.field_info, params.Body) + ] + if len(set(body_param_media_types)) == 1: + BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0] + final_field = create_model_field( + name="body", + type_=BodyModel, + required=required, + alias="body", + field_info=BodyFieldInfo(**BodyFieldInfo_kwargs), + ) + return final_field diff --git a/venv/lib/python3.11/site-packages/fastapi/encoders.py b/venv/lib/python3.11/site-packages/fastapi/encoders.py new file mode 100644 index 0000000..451ea07 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/encoders.py @@ -0,0 +1,343 @@ +import dataclasses +import datetime +from collections import defaultdict, deque +from decimal import Decimal +from enum import Enum +from ipaddress import ( + IPv4Address, + IPv4Interface, + IPv4Network, + IPv6Address, + IPv6Interface, + IPv6Network, +) +from pathlib import Path, PurePath +from re import Pattern +from types import GeneratorType +from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union +from uuid import UUID + +from fastapi.types import IncEx +from pydantic import BaseModel +from pydantic.color import Color +from pydantic.networks import AnyUrl, NameEmail +from pydantic.types import SecretBytes, SecretStr +from typing_extensions import Annotated, Doc + +from ._compat import PYDANTIC_V2, UndefinedType, Url, _model_dump + + +# Taken from Pydantic v1 as is +def isoformat(o: Union[datetime.date, datetime.time]) -> str: + return o.isoformat() + + +# Taken from Pydantic v1 as is +# TODO: pv2 should this return strings instead? +def decimal_encoder(dec_value: Decimal) -> Union[int, float]: + """ + Encodes a Decimal as int of there's no exponent, otherwise float + + This is useful when we use ConstrainedDecimal to represent Numeric(x,0) + where a integer (but not int typed) is used. Encoding this as a float + results in failed round-tripping between encode and parse. + Our Id type is a prime example of this. + + >>> decimal_encoder(Decimal("1.0")) + 1.0 + + >>> decimal_encoder(Decimal("1")) + 1 + """ + if dec_value.as_tuple().exponent >= 0: # type: ignore[operator] + return int(dec_value) + else: + return float(dec_value) + + +ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = { + bytes: lambda o: o.decode(), + Color: str, + datetime.date: isoformat, + datetime.datetime: isoformat, + datetime.time: isoformat, + datetime.timedelta: lambda td: td.total_seconds(), + Decimal: decimal_encoder, + Enum: lambda o: o.value, + frozenset: list, + deque: list, + GeneratorType: list, + IPv4Address: str, + IPv4Interface: str, + IPv4Network: str, + IPv6Address: str, + IPv6Interface: str, + IPv6Network: str, + NameEmail: str, + Path: str, + Pattern: lambda o: o.pattern, + SecretBytes: str, + SecretStr: str, + set: list, + UUID: str, + Url: str, + AnyUrl: str, +} + + +def generate_encoders_by_class_tuples( + type_encoder_map: Dict[Any, Callable[[Any], Any]], +) -> Dict[Callable[[Any], Any], Tuple[Any, ...]]: + encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict( + tuple + ) + for type_, encoder in type_encoder_map.items(): + encoders_by_class_tuples[encoder] += (type_,) + return encoders_by_class_tuples + + +encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE) + + +def jsonable_encoder( + obj: Annotated[ + Any, + Doc( + """ + The input object to convert to JSON. + """ + ), + ], + include: Annotated[ + Optional[IncEx], + Doc( + """ + Pydantic's `include` parameter, passed to Pydantic models to set the + fields to include. + """ + ), + ] = None, + exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Pydantic's `exclude` parameter, passed to Pydantic models to set the + fields to exclude. + """ + ), + ] = None, + by_alias: Annotated[ + bool, + Doc( + """ + Pydantic's `by_alias` parameter, passed to Pydantic models to define if + the output should use the alias names (when provided) or the Python + attribute names. In an API, if you set an alias, it's probably because you + want to use it in the result, so you probably want to leave this set to + `True`. + """ + ), + ] = True, + exclude_unset: Annotated[ + bool, + Doc( + """ + Pydantic's `exclude_unset` parameter, passed to Pydantic models to define + if it should exclude from the output the fields that were not explicitly + set (and that only had their default values). + """ + ), + ] = False, + exclude_defaults: Annotated[ + bool, + Doc( + """ + Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define + if it should exclude from the output the fields that had the same default + value, even when they were explicitly set. + """ + ), + ] = False, + exclude_none: Annotated[ + bool, + Doc( + """ + Pydantic's `exclude_none` parameter, passed to Pydantic models to define + if it should exclude from the output any fields that have a `None` value. + """ + ), + ] = False, + custom_encoder: Annotated[ + Optional[Dict[Any, Callable[[Any], Any]]], + Doc( + """ + Pydantic's `custom_encoder` parameter, passed to Pydantic models to define + a custom encoder. + """ + ), + ] = None, + sqlalchemy_safe: Annotated[ + bool, + Doc( + """ + Exclude from the output any fields that start with the name `_sa`. + + This is mainly a hack for compatibility with SQLAlchemy objects, they + store internal SQLAlchemy-specific state in attributes named with `_sa`, + and those objects can't (and shouldn't be) serialized to JSON. + """ + ), + ] = True, +) -> Any: + """ + Convert any object to something that can be encoded in JSON. + + This is used internally by FastAPI to make sure anything you return can be + encoded as JSON before it is sent to the client. + + You can also use it yourself, for example to convert objects before saving them + in a database that supports only JSON. + + Read more about it in the + [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/). + """ + custom_encoder = custom_encoder or {} + if custom_encoder: + if type(obj) in custom_encoder: + return custom_encoder[type(obj)](obj) + else: + for encoder_type, encoder_instance in custom_encoder.items(): + if isinstance(obj, encoder_type): + return encoder_instance(obj) + if include is not None and not isinstance(include, (set, dict)): + include = set(include) + if exclude is not None and not isinstance(exclude, (set, dict)): + exclude = set(exclude) + if isinstance(obj, BaseModel): + # TODO: remove when deprecating Pydantic v1 + encoders: Dict[Any, Any] = {} + if not PYDANTIC_V2: + encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined] + if custom_encoder: + encoders.update(custom_encoder) + obj_dict = _model_dump( + obj, + mode="json", + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_none=exclude_none, + exclude_defaults=exclude_defaults, + ) + if "__root__" in obj_dict: + obj_dict = obj_dict["__root__"] + return jsonable_encoder( + obj_dict, + exclude_none=exclude_none, + exclude_defaults=exclude_defaults, + # TODO: remove when deprecating Pydantic v1 + custom_encoder=encoders, + sqlalchemy_safe=sqlalchemy_safe, + ) + if dataclasses.is_dataclass(obj): + obj_dict = dataclasses.asdict(obj) + return jsonable_encoder( + obj_dict, + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) + if isinstance(obj, Enum): + return obj.value + if isinstance(obj, PurePath): + return str(obj) + if isinstance(obj, (str, int, float, type(None))): + return obj + if isinstance(obj, UndefinedType): + return None + if isinstance(obj, dict): + encoded_dict = {} + allowed_keys = set(obj.keys()) + if include is not None: + allowed_keys &= set(include) + if exclude is not None: + allowed_keys -= set(exclude) + for key, value in obj.items(): + if ( + ( + not sqlalchemy_safe + or (not isinstance(key, str)) + or (not key.startswith("_sa")) + ) + and (value is not None or not exclude_none) + and key in allowed_keys + ): + encoded_key = jsonable_encoder( + key, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_none=exclude_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) + encoded_value = jsonable_encoder( + value, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_none=exclude_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) + encoded_dict[encoded_key] = encoded_value + return encoded_dict + if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)): + encoded_list = [] + for item in obj: + encoded_list.append( + jsonable_encoder( + item, + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) + ) + return encoded_list + + if type(obj) in ENCODERS_BY_TYPE: + return ENCODERS_BY_TYPE[type(obj)](obj) + for encoder, classes_tuple in encoders_by_class_tuples.items(): + if isinstance(obj, classes_tuple): + return encoder(obj) + + try: + data = dict(obj) + except Exception as e: + errors: List[Exception] = [] + errors.append(e) + try: + data = vars(obj) + except Exception as e: + errors.append(e) + raise ValueError(errors) from e + return jsonable_encoder( + data, + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + custom_encoder=custom_encoder, + sqlalchemy_safe=sqlalchemy_safe, + ) diff --git a/venv/lib/python3.11/site-packages/fastapi/exception_handlers.py b/venv/lib/python3.11/site-packages/fastapi/exception_handlers.py new file mode 100644 index 0000000..6c2ba7f --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/exception_handlers.py @@ -0,0 +1,34 @@ +from fastapi.encoders import jsonable_encoder +from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError +from fastapi.utils import is_body_allowed_for_status_code +from fastapi.websockets import WebSocket +from starlette.exceptions import HTTPException +from starlette.requests import Request +from starlette.responses import JSONResponse, Response +from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, WS_1008_POLICY_VIOLATION + + +async def http_exception_handler(request: Request, exc: HTTPException) -> Response: + headers = getattr(exc, "headers", None) + if not is_body_allowed_for_status_code(exc.status_code): + return Response(status_code=exc.status_code, headers=headers) + return JSONResponse( + {"detail": exc.detail}, status_code=exc.status_code, headers=headers + ) + + +async def request_validation_exception_handler( + request: Request, exc: RequestValidationError +) -> JSONResponse: + return JSONResponse( + status_code=HTTP_422_UNPROCESSABLE_ENTITY, + content={"detail": jsonable_encoder(exc.errors())}, + ) + + +async def websocket_request_validation_exception_handler( + websocket: WebSocket, exc: WebSocketRequestValidationError +) -> None: + await websocket.close( + code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors()) + ) diff --git a/venv/lib/python3.11/site-packages/fastapi/exceptions.py b/venv/lib/python3.11/site-packages/fastapi/exceptions.py new file mode 100644 index 0000000..44d4ada --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/exceptions.py @@ -0,0 +1,176 @@ +from typing import Any, Dict, Optional, Sequence, Type, Union + +from pydantic import BaseModel, create_model +from starlette.exceptions import HTTPException as StarletteHTTPException +from starlette.exceptions import WebSocketException as StarletteWebSocketException +from typing_extensions import Annotated, Doc + + +class HTTPException(StarletteHTTPException): + """ + An HTTP exception you can raise in your own code to show errors to the client. + + This is for client errors, invalid authentication, invalid data, etc. Not for server + errors in your code. + + Read more about it in the + [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). + + ## Example + + ```python + from fastapi import FastAPI, HTTPException + + app = FastAPI() + + items = {"foo": "The Foo Wrestlers"} + + + @app.get("/items/{item_id}") + async def read_item(item_id: str): + if item_id not in items: + raise HTTPException(status_code=404, detail="Item not found") + return {"item": items[item_id]} + ``` + """ + + def __init__( + self, + status_code: Annotated[ + int, + Doc( + """ + HTTP status code to send to the client. + """ + ), + ], + detail: Annotated[ + Any, + Doc( + """ + Any data to be sent to the client in the `detail` key of the JSON + response. + """ + ), + ] = None, + headers: Annotated[ + Optional[Dict[str, str]], + Doc( + """ + Any headers to send to the client in the response. + """ + ), + ] = None, + ) -> None: + super().__init__(status_code=status_code, detail=detail, headers=headers) + + +class WebSocketException(StarletteWebSocketException): + """ + A WebSocket exception you can raise in your own code to show errors to the client. + + This is for client errors, invalid authentication, invalid data, etc. Not for server + errors in your code. + + Read more about it in the + [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). + + ## Example + + ```python + from typing import Annotated + + from fastapi import ( + Cookie, + FastAPI, + WebSocket, + WebSocketException, + status, + ) + + app = FastAPI() + + @app.websocket("/items/{item_id}/ws") + async def websocket_endpoint( + *, + websocket: WebSocket, + session: Annotated[str | None, Cookie()] = None, + item_id: str, + ): + if session is None: + raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) + await websocket.accept() + while True: + data = await websocket.receive_text() + await websocket.send_text(f"Session cookie is: {session}") + await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}") + ``` + """ + + def __init__( + self, + code: Annotated[ + int, + Doc( + """ + A closing code from the + [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1). + """ + ), + ], + reason: Annotated[ + Union[str, None], + Doc( + """ + The reason to close the WebSocket connection. + + It is UTF-8-encoded data. The interpretation of the reason is up to the + application, it is not specified by the WebSocket specification. + + It could contain text that could be human-readable or interpretable + by the client code, etc. + """ + ), + ] = None, + ) -> None: + super().__init__(code=code, reason=reason) + + +RequestErrorModel: Type[BaseModel] = create_model("Request") +WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket") + + +class FastAPIError(RuntimeError): + """ + A generic, FastAPI-specific error. + """ + + +class ValidationException(Exception): + def __init__(self, errors: Sequence[Any]) -> None: + self._errors = errors + + def errors(self) -> Sequence[Any]: + return self._errors + + +class RequestValidationError(ValidationException): + def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None: + super().__init__(errors) + self.body = body + + +class WebSocketRequestValidationError(ValidationException): + pass + + +class ResponseValidationError(ValidationException): + def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None: + super().__init__(errors) + self.body = body + + def __str__(self) -> str: + message = f"{len(self._errors)} validation errors:\n" + for err in self._errors: + message += f" {err}\n" + return message diff --git a/venv/lib/python3.11/site-packages/fastapi/logger.py b/venv/lib/python3.11/site-packages/fastapi/logger.py new file mode 100644 index 0000000..5b2c4ad --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/logger.py @@ -0,0 +1,3 @@ +import logging + +logger = logging.getLogger("fastapi") diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/__init__.py b/venv/lib/python3.11/site-packages/fastapi/middleware/__init__.py new file mode 100644 index 0000000..620296d --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/middleware/__init__.py @@ -0,0 +1 @@ +from starlette.middleware import Middleware as Middleware diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65ec35a57b00955b7b62eda686a567821ff4d124 GIT binary patch literal 266 zcmZ3^%ge<81aZ$^r&|H(#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ*lo%rljPgmM0da`e`!V5-Bc8EXqkODM{7Kg-aAM1J$l%_zcqWD?-04u}HtXyj(vu zH$N*gwJblUv?Mb>ProcRuS`EDGfBUovLquv&sfjUP`@~{BvrQ{F*!RiJ+)XrEfHvX zL8d;!Wc~Q~%)HE!_;|g7%3mBdx%nxjIjMF<96*a0fw))}NPJ*sWMsU-V0i%>Dq;hw F003r6OZ5N% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/cors.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/cors.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d735807df5c2205f0cf0705c4c8005dcaabc7819 GIT binary patch literal 271 zcmZ3^%ge<81aZ$^r~3ox#~=<2FhLogg@BCd3@HpLj5!Rsj8Tk?3@J>(44TX@K?*b( zZ}B<%2L=0PrljPgmM0da`e`!Vk}NJsEXqkODM{7Kg-hrq=NAR zF+H_dKP?exMM0)M!gzg<@p=W7zc_4i^HWN5QtgU3fR-=(44TX@K?*b( zZ}GWDWfu5mrljPgmM0da`e`!Vk}NJsEXqkODM{7Kg-htAS7jCyF#|QNWcUoy`zu7h zEU`$xyu4gLH8(#iGqo%~r?ez9KTp3bHLpxRCo@UEpt2+*KhIdt&``fPvm{lwATc>R zF+H_dKP?exMM0)M!gzg<@p=W7zc_4i^HWN5QtgU3fR-=qDi{wRUyI27y&JwEk774q@glU)U_}Xc07A>D$g|JxAcyVQ zcs9G4-jX(f=4oQIw$!LV*SXxD$E1R#l&C0w7R53pAH(q>WNh;$cAeY)9%~h_X&R)` zJsYZ>T_@uztf{Kenn(1Tv~<-)F&besiH2UyS872KpA=_#gTFcWC#Ue6eebe#dTr?{ X^f(Q;;*hD$0HBo;WGnuqaKax4pSW0s literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7b9697453b15eff10a9b8fbcff7743f8a98904c GIT binary patch literal 308 zcmah?Jxc^Z44uq^9Ktn%z3mpa;jk5J8*Q{w5Jo57jn3>WGud74m-rLJzjUo2h|R)v zSDD4n&Id_e$jf_A)9J1fT))0Ag3On3`G)=?n>`_q$|?(91-JxIR-db~cpC*JtoJWc zo0;rM%zWys_0*e0XQf^rWH!kYGgaZ|Q1PdHDe_c^#k1OsPTMQ&Ov1kJkwUz8)J5O2 zi#2vscj(;>HY;An`mmbMF*~MNV{RYJf->G2NopMarr@8Hs#$F(M(44TX@K?*b( zZ}Ei(yLR zF+H_dKP?exMM0)M!gzg<@p=W7zc_4i^HWN5QtgU3fR-=BLDyZ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/cors.py b/venv/lib/python3.11/site-packages/fastapi/middleware/cors.py new file mode 100644 index 0000000..8dfaad0 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/middleware/cors.py @@ -0,0 +1 @@ +from starlette.middleware.cors import CORSMiddleware as CORSMiddleware # noqa diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/gzip.py b/venv/lib/python3.11/site-packages/fastapi/middleware/gzip.py new file mode 100644 index 0000000..bbeb2cc --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/middleware/gzip.py @@ -0,0 +1 @@ +from starlette.middleware.gzip import GZipMiddleware as GZipMiddleware # noqa diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/httpsredirect.py b/venv/lib/python3.11/site-packages/fastapi/middleware/httpsredirect.py new file mode 100644 index 0000000..b7a3d8e --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/middleware/httpsredirect.py @@ -0,0 +1,3 @@ +from starlette.middleware.httpsredirect import ( # noqa + HTTPSRedirectMiddleware as HTTPSRedirectMiddleware, +) diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/trustedhost.py b/venv/lib/python3.11/site-packages/fastapi/middleware/trustedhost.py new file mode 100644 index 0000000..08d7e03 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/middleware/trustedhost.py @@ -0,0 +1,3 @@ +from starlette.middleware.trustedhost import ( # noqa + TrustedHostMiddleware as TrustedHostMiddleware, +) diff --git a/venv/lib/python3.11/site-packages/fastapi/middleware/wsgi.py b/venv/lib/python3.11/site-packages/fastapi/middleware/wsgi.py new file mode 100644 index 0000000..c4c6a79 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/middleware/wsgi.py @@ -0,0 +1 @@ +from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware # noqa diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/__init__.py b/venv/lib/python3.11/site-packages/fastapi/openapi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..431ff8364f5b356d33e2438e4a30526ab2d5dc4e GIT binary patch literal 194 zcmZ3^%ge<81aZ$^r-SInAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnuTcH6#3KFj z@^byu-2AM})Uy1X(vr;lJpHoNyfXcq%q0DS%94!yJYzjWL;d2+l2qM-#N_P6^weVg zw8Y|)#DYxy{DRax5FH<%nU`4-AFo$X`HRCQH$SB`C)KWq6=(~{9mV`W;sY}yBjX1K K7*WIw6axTOEHcFa literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/constants.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/constants.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..728adf5c075d5d36b16555bc27fdc25cf2a42ea7 GIT binary patch literal 364 zcmZ3^%ge<81aZ$^r_Th^k3k$5V1hC}ivbza88R4B7#1@|F{Cg?F{Us@F{LmEGib8d zu>mD-F}u5l++q$04Y|eQ;p*seizUE6IOG;EFQ_cZ$j>v@Gc?pM&MZmQEl5nxPE1cN)=x_;E=erN)Xy(S%>&WN`FTJApp*3q zDt~d<0NquZlWJGQ2egI}h>PWc#0O?ZM#dW=t`{JPLGT8zN(0voe%%Hh5G>*WssRAz Cwrx}Z literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/docs.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/docs.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5bf1c6e04d2028a1be09b279b83f5bd78ffa52d GIT binary patch literal 11442 zcmd5?U2Gdyb{_tU6e(M_Y}rx#b46P}v?bDR(%p@0*|8;Ot-yb^tRySPD~~u=;yA+@ zW@acwG*#rmC{$n{QXoZwHU_f5cH71Fp+H~ShXQ@*b0Gy{cbLZT1&pr3tbG~zif8Ev9DdF?u|M>4kZCH~2oo>9(QTO8OL`0H4 zk!B=CQbL+EOW$EFR0_|AOOe?~DLNYsQC~!hmEyB;aUIn90 z_;>KLxY7-7U1Id1-A5~jeX5>4sE+tlNB5xW^{I~SL3P}xdT9@;K2Sw@SDPMQ-ebfG zF=Ctk+BlrtgTtwPaX7sP2gVZ%hn4OmkwM_RpW}MLP`LSvP(6L~!R=f3xm7lFi)X|2jows=io1U=@w! z8z0zQw=lm|KSK8tMyX`z&ED#tbTaod$rt2`X0w8!FQ|(ZQzo%3wqTfS+L3_GOyxR# z`X3n;R*-d8u{cw0CR*Z3usi9Ftwd~jbu(fBtqAME5 zpz8RyW|AvdR&~T1z93t+Tvl_oD(j1eX5(#+H>Mb{irtznrdpOo-)c@hg3vg z{U=|sw7Cz8oZZFKYxkzu%>7%;F3NVxo-!ClMN^n&$h2b$?P$wBI~-Jt;ZHZrlB{Vf zOfhuMAgED-nG{6V{0e&milIp=77P&6aOQ3$O&bvDao!ad`(o&in}$HM)nm45YrOhS zU(&I)^cSvhH0J+)17jHdYez!Vd$PLef`;qLB| z3>&(14}?Yfeb{o6xBI+D4?REQ9TmkWSh>B&1SPM>O>S3Ay?_OXPXcWU|AE@1um2SY z>J!Np51i(6A5*n-NA1OE{L`@;FbA9%o&@M6h64#1lhDprF_Qo;ctO6(O^pMr! zr^Wi4Zu34zkSiG`^fC_=C7h3l7Gj=b&4m-{F0PCWS0y&J4(m$WP5(dE`l=*;ca04|xmQs(0sn}1;E0cA3< zE^Rzx*((~iik#aSRy6s-c&0j(X&vQI6%EraklvvlpYVW3=mhraTbJ|Bl_N^N*c4#i zP*z;7in_#91vC5j*khB&BbUe$!J1iS0RlbCT)CWgdfdnTqoeGxYdJGh*9BC3?1ZCb zhFGs^1lO720E)7_$l2& zmv5R^HenuuQ>#Y{MtP+kuap&dt$IvFE@9Q91P|*mrBW(eW*lTDg|KYeJWkh?%?d1M z5}+~(+?a$sOacWah3)#uLd7(J5$7xyj0aJ3l;o&K-s3Cv*pjSOxRu5zT7&ob%^&5L zWHZ0KyqxDHMXUA&mLAogfkF1!azv5*glM8U(l z!cpe1$eu+W5Qu~@2QhIU{#(n4!XHY%*2B`k_0X4R-}vI}8yjbDZl1ll9_`=iIMI+o zvB}U@V&Kcf$QOx`_0j7aiHXg`#Cl?)5$#SV8VTu@>!C)HE+uL@rNP%4DgQPtbscVW z`M14NPk-Z>e|t*mez|elza<7APBzX;$6o!i_q8v2U)$)twAp)!WVjo0+CS}Fi>%FT zCDMQX>c?ZB7XIw&$5+?8@8IvRl%GBM)x~T7Jg{-`=H|tl8-r7ugHz5Uv>S;#Ytgmn zR~>!C<{d03z25!y`s>rwiocD-+jt(uDq>xoFQizk6OtT|5{Da7B$ft!Lkb^C|66b0 z$4`FMfAR0mZS;?C_K$D$UfJxu(um-ZcrKb3QaG7ji$XQAWJ8K}C0UVXxh@gQNyUfVAlLvcE&lU2Cd$ zh_LD0qG2qeBCvp5#;X2HqSO7_t)p-6Hs0v*4Di%$r>5@HQMkF3UO zQ8QMHDGuVJtEfP>E{+wLw&Qt+z-ckN1xeRp+i+S!{zni9VfVyo@WG-k1hnAeHAi(G zRFgG8H61Zxe^5;r;r~BY6KnWRVcP#KZu*|sy59jexxnTxg20B*hl_q`KV?Nmt#FB| zCYHLWH<1R4U@|KdWx!^8JX5h3Mt_jWyC_6F(@`fI&n&5YxeR=j@d_j3nPpY6i{lDM zU5by28|2$g>N{!yoAdFDE@-M&oiz!B=Kwe#<%%=o_$k5>qTU7McXdH7soKi;ZF&ym zF56?TT(~guD*k`}!iCy>W8Sch)~@YP(OE=wpk?meaiV+~hsMKr(483M90$eVmOg~y zCF%vhXh8O;`v|z^;8H=_L~evtov9fkRKl7dtt6WOT4U_OB{7EFa2cgcAnumFRY%^u zVD4_jE+|zuS^+1qb0jwT`xO-UoK(d{sYqqKEGftCX&l8~hN2!JP!vh<)TwBR+yOzT zQUb7X;Gru|aI(wdv@@&B3!}iE0Kg{*0E=E%=m0#R$Zb;NH=~$-G@84#mp3{vp{wgEV+W@^k6`M#U61ijiW2ci8K3{moK*(OSLL(Q}1**`NYIvdWm983}gNSryz5)v&p zMWX5$H@&*p%#9>b^$D7$D7qdB&<4sI~4-Z`(8ev0&L)oCTtBh;V|5ITc#Mb)=_C8;W%Vr_S zxs6Y7g;+DBd%v8s%9?5qX9hEE^MW9USa(A%6o>u29$p$zN9OPd>t*!)P<;e8Lzy8Y zyi3icjMGvwW0|2WCBm7ZORH_%h45&uvNxyi-pQeYWI+Q@i49Hs#87qE6vnQ)Ik>lK z@4G1yQo<3~8&blZHo>EJ3u_=|&m3KQ&>LfZ||w!w$co20d0z zO!4lrVDNOc-F_VNay9JOFlO~Fx}6;6Hr%$s&gsd~*~nRiA}`4~c;(^Df@Umdvd$vp zLV;V>1ccA9TJ75~0CyBDoZ9+##b=JRnF&afWrKsPzjaAOv(tXj$?JDd=T6T_?Jgf2 z%8B`ws*SfJ-Z!akN*VLWg(eAqIRz4rs`cAK!Lz`}ScYgbyVGfWiKFzBS(Z&5r+5#_ z67~lb2GCw>RW&QgD{P*#if+jZd<4J+ZwoQII6by&=Ip@D|#B6sdnT=p3kvHUjQpw|ycKyxhf0Ur)a~_+}!aPy5C@=Ym-8 ze8OCMDoM|yL^J%9Ru$OD5&zYcD8jY)`W=_In-3-7um(rK8|36~TZ=o(~eQrp?@@8oa767?{Oh30_{SG;Mp-@D{X#LD8e%o0BUv zxu0_@B);KV2AnMRGkB60P06#3o_RCn!L_%R8A%i*EPySMQsh<`&^{gw)upr1IwYF{UuvO zi60Mj;2i@A;N)H*C&i*Nlbc6a9=;<@R>vP)cswON$+t@`l+EQUIRn`Ve1Fy=49t*P;gS#+?*(m*Q4`> zp_!C5nzW8zNJ2!BTmB|-xnw96WcB6`@QBo6{U?NNL_(p^mX!L?{kJ6zuJ8W$l{C5@ z{M(X7)`NfBdmMtsap~ZRtpj~qJ;%0s`?gN7Mk*c)HzaC$q|m8PSGJ;wwVt)Y+VN+1 zwxS&$PBg;NWco!U9*chis(2&P5$pISl4KZkFyu5Z#MR@Fl)Mva9FdYYLyc}J`F(1- zoCcj;jhXOdICQEZHQTQa^=&0m_*;uK!m+OI7m#* z+N2E=ZIo!yG$Jvg?MTNPFALgp($P~*+9=V+i53mSC)(uEc;mdFy(0CV{w=h<@y1m_ zdp{)gooN#9C`4bpF&z@r^A2_QM?F93!XR4WZX*iL2s0#+Lb^XX@=@W_S3W9!d}=en z_8NL9-msjZ*Td3@fnA2~sDKmk#)PvUZ-u4!;l|tBHpktlH)CR3n;ZHl^lpf@vDxl# z8wLG7w^7iZlX^}xwY}pida#Xx_KI}8ze&5Jo{wW21?`=XAjZ3y-8Tiqcb#?qI7I51 a+qP&|0e>8RClng|n|B)$eec~0NAN#PY2P#e literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/models.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/models.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa669de0ce7eb9867bc5c900e5ffdc089fd6a379 GIT binary patch literal 28940 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/openapi/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc509ce8c37ef0b2083872c5ff94e20124845ca0 GIT binary patch literal 23300 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 content, normally shown in the browser tab. + """ + ), + ], + swagger_js_url: Annotated[ + str, + Doc( + """ + The URL to use to load the Swagger UI JavaScript. + + It is normally set to a CDN URL. + """ + ), + ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js", + swagger_css_url: Annotated[ + str, + Doc( + """ + The URL to use to load the Swagger UI CSS. + + It is normally set to a CDN URL. + """ + ), + ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css", + swagger_favicon_url: Annotated[ + str, + Doc( + """ + The URL of the favicon to use. It is normally shown in the browser tab. + """ + ), + ] = "https://fastapi.tiangolo.com/img/favicon.png", + oauth2_redirect_url: Annotated[ + Optional[str], + Doc( + """ + The OAuth2 redirect URL, it is normally automatically handled by FastAPI. + """ + ), + ] = None, + init_oauth: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + A dictionary with Swagger UI OAuth2 initialization configurations. + """ + ), + ] = None, + swagger_ui_parameters: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Configuration parameters for Swagger UI. + + It defaults to [swagger_ui_default_parameters][fastapi.openapi.docs.swagger_ui_default_parameters]. + """ + ), + ] = None, +) -> HTMLResponse: + """ + Generate and return the HTML that loads Swagger UI for the interactive + API docs (normally served at `/docs`). + + You would only call this function yourself if you needed to override some parts, + for example the URLs to use to load Swagger UI's JavaScript and CSS. + + Read more about it in the + [FastAPI docs for Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/) + and the [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/). + """ + current_swagger_ui_parameters = swagger_ui_default_parameters.copy() + if swagger_ui_parameters: + current_swagger_ui_parameters.update(swagger_ui_parameters) + + html = f""" + + + + + + {title} + + +
    +
    + + + + + + """ + return HTMLResponse(html) + + +def get_redoc_html( + *, + openapi_url: Annotated[ + str, + Doc( + """ + The OpenAPI URL that ReDoc should load and use. + + This is normally done automatically by FastAPI using the default URL + `/openapi.json`. + """ + ), + ], + title: Annotated[ + str, + Doc( + """ + The HTML `` content, normally shown in the browser tab. + """ + ), + ], + redoc_js_url: Annotated[ + str, + Doc( + """ + The URL to use to load the ReDoc JavaScript. + + It is normally set to a CDN URL. + """ + ), + ] = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js", + redoc_favicon_url: Annotated[ + str, + Doc( + """ + The URL of the favicon to use. It is normally shown in the browser tab. + """ + ), + ] = "https://fastapi.tiangolo.com/img/favicon.png", + with_google_fonts: Annotated[ + bool, + Doc( + """ + Load and use Google Fonts. + """ + ), + ] = True, +) -> HTMLResponse: + """ + Generate and return the HTML response that loads ReDoc for the alternative + API docs (normally served at `/redoc`). + + You would only call this function yourself if you needed to override some parts, + for example the URLs to use to load ReDoc's JavaScript and CSS. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/). + """ + html = f""" + <!DOCTYPE html> + <html> + <head> + <title>{title} + + + + """ + if with_google_fonts: + html += """ + + """ + html += f""" + + + + + + + + + + + """ + return HTMLResponse(html) + + +def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse: + """ + Generate the HTML response with the OAuth2 redirection for Swagger UI. + + You normally don't need to use or change this. + """ + # copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html + html = """ + + + + Swagger UI: OAuth2 Redirect + + + + + + """ + return HTMLResponse(content=html) diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/models.py b/venv/lib/python3.11/site-packages/fastapi/openapi/models.py new file mode 100644 index 0000000..ed07b40 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/openapi/models.py @@ -0,0 +1,445 @@ +from enum import Enum +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union + +from fastapi._compat import ( + PYDANTIC_V2, + CoreSchema, + GetJsonSchemaHandler, + JsonSchemaValue, + _model_rebuild, + with_info_plain_validator_function, +) +from fastapi.logger import logger +from pydantic import AnyUrl, BaseModel, Field +from typing_extensions import Annotated, Literal, TypedDict +from typing_extensions import deprecated as typing_deprecated + +try: + import email_validator + + assert email_validator # make autoflake ignore the unused import + from pydantic import EmailStr +except ImportError: # pragma: no cover + + class EmailStr(str): # type: ignore + @classmethod + def __get_validators__(cls) -> Iterable[Callable[..., Any]]: + yield cls.validate + + @classmethod + def validate(cls, v: Any) -> str: + logger.warning( + "email-validator not installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(v) + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> str: + logger.warning( + "email-validator not installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(__input_value) + + @classmethod + def __get_pydantic_json_schema__( + cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler + ) -> JsonSchemaValue: + return {"type": "string", "format": "email"} + + @classmethod + def __get_pydantic_core_schema__( + cls, source: Type[Any], handler: Callable[[Any], CoreSchema] + ) -> CoreSchema: + return with_info_plain_validator_function(cls._validate) + + +class BaseModelWithConfig(BaseModel): + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class Contact(BaseModelWithConfig): + name: Optional[str] = None + url: Optional[AnyUrl] = None + email: Optional[EmailStr] = None + + +class License(BaseModelWithConfig): + name: str + identifier: Optional[str] = None + url: Optional[AnyUrl] = None + + +class Info(BaseModelWithConfig): + title: str + summary: Optional[str] = None + description: Optional[str] = None + termsOfService: Optional[str] = None + contact: Optional[Contact] = None + license: Optional[License] = None + version: str + + +class ServerVariable(BaseModelWithConfig): + enum: Annotated[Optional[List[str]], Field(min_length=1)] = None + default: str + description: Optional[str] = None + + +class Server(BaseModelWithConfig): + url: Union[AnyUrl, str] + description: Optional[str] = None + variables: Optional[Dict[str, ServerVariable]] = None + + +class Reference(BaseModel): + ref: str = Field(alias="$ref") + + +class Discriminator(BaseModel): + propertyName: str + mapping: Optional[Dict[str, str]] = None + + +class XML(BaseModelWithConfig): + name: Optional[str] = None + namespace: Optional[str] = None + prefix: Optional[str] = None + attribute: Optional[bool] = None + wrapped: Optional[bool] = None + + +class ExternalDocumentation(BaseModelWithConfig): + description: Optional[str] = None + url: AnyUrl + + +class Schema(BaseModelWithConfig): + # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-json-schema-core-vocabu + # Core Vocabulary + schema_: Optional[str] = Field(default=None, alias="$schema") + vocabulary: Optional[str] = Field(default=None, alias="$vocabulary") + id: Optional[str] = Field(default=None, alias="$id") + anchor: Optional[str] = Field(default=None, alias="$anchor") + dynamicAnchor: Optional[str] = Field(default=None, alias="$dynamicAnchor") + ref: Optional[str] = Field(default=None, alias="$ref") + dynamicRef: Optional[str] = Field(default=None, alias="$dynamicRef") + defs: Optional[Dict[str, "SchemaOrBool"]] = Field(default=None, alias="$defs") + comment: Optional[str] = Field(default=None, alias="$comment") + # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-a-vocabulary-for-applying-s + # A Vocabulary for Applying Subschemas + allOf: Optional[List["SchemaOrBool"]] = None + anyOf: Optional[List["SchemaOrBool"]] = None + oneOf: Optional[List["SchemaOrBool"]] = None + not_: Optional["SchemaOrBool"] = Field(default=None, alias="not") + if_: Optional["SchemaOrBool"] = Field(default=None, alias="if") + then: Optional["SchemaOrBool"] = None + else_: Optional["SchemaOrBool"] = Field(default=None, alias="else") + dependentSchemas: Optional[Dict[str, "SchemaOrBool"]] = None + prefixItems: Optional[List["SchemaOrBool"]] = None + # TODO: uncomment and remove below when deprecating Pydantic v1 + # It generales a list of schemas for tuples, before prefixItems was available + # items: Optional["SchemaOrBool"] = None + items: Optional[Union["SchemaOrBool", List["SchemaOrBool"]]] = None + contains: Optional["SchemaOrBool"] = None + properties: Optional[Dict[str, "SchemaOrBool"]] = None + patternProperties: Optional[Dict[str, "SchemaOrBool"]] = None + additionalProperties: Optional["SchemaOrBool"] = None + propertyNames: Optional["SchemaOrBool"] = None + unevaluatedItems: Optional["SchemaOrBool"] = None + unevaluatedProperties: Optional["SchemaOrBool"] = None + # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural + # A Vocabulary for Structural Validation + type: Optional[str] = None + enum: Optional[List[Any]] = None + const: Optional[Any] = None + multipleOf: Optional[float] = Field(default=None, gt=0) + maximum: Optional[float] = None + exclusiveMaximum: Optional[float] = None + minimum: Optional[float] = None + exclusiveMinimum: Optional[float] = None + maxLength: Optional[int] = Field(default=None, ge=0) + minLength: Optional[int] = Field(default=None, ge=0) + pattern: Optional[str] = None + maxItems: Optional[int] = Field(default=None, ge=0) + minItems: Optional[int] = Field(default=None, ge=0) + uniqueItems: Optional[bool] = None + maxContains: Optional[int] = Field(default=None, ge=0) + minContains: Optional[int] = Field(default=None, ge=0) + maxProperties: Optional[int] = Field(default=None, ge=0) + minProperties: Optional[int] = Field(default=None, ge=0) + required: Optional[List[str]] = None + dependentRequired: Optional[Dict[str, Set[str]]] = None + # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-vocabularies-for-semantic-c + # Vocabularies for Semantic Content With "format" + format: Optional[str] = None + # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-the-conten + # A Vocabulary for the Contents of String-Encoded Data + contentEncoding: Optional[str] = None + contentMediaType: Optional[str] = None + contentSchema: Optional["SchemaOrBool"] = None + # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-basic-meta + # A Vocabulary for Basic Meta-Data Annotations + title: Optional[str] = None + description: Optional[str] = None + default: Optional[Any] = None + deprecated: Optional[bool] = None + readOnly: Optional[bool] = None + writeOnly: Optional[bool] = None + examples: Optional[List[Any]] = None + # Ref: OpenAPI 3.1.0: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schema-object + # Schema Object + discriminator: Optional[Discriminator] = None + xml: Optional[XML] = None + externalDocs: Optional[ExternalDocumentation] = None + example: Annotated[ + Optional[Any], + typing_deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = None + + +# Ref: https://json-schema.org/draft/2020-12/json-schema-core.html#name-json-schema-documents +# A JSON Schema MUST be an object or a boolean. +SchemaOrBool = Union[Schema, bool] + + +class Example(TypedDict, total=False): + summary: Optional[str] + description: Optional[str] + value: Optional[Any] + externalValue: Optional[AnyUrl] + + if PYDANTIC_V2: # type: ignore [misc] + __pydantic_config__ = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class ParameterInType(Enum): + query = "query" + header = "header" + path = "path" + cookie = "cookie" + + +class Encoding(BaseModelWithConfig): + contentType: Optional[str] = None + headers: Optional[Dict[str, Union["Header", Reference]]] = None + style: Optional[str] = None + explode: Optional[bool] = None + allowReserved: Optional[bool] = None + + +class MediaType(BaseModelWithConfig): + schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema") + example: Optional[Any] = None + examples: Optional[Dict[str, Union[Example, Reference]]] = None + encoding: Optional[Dict[str, Encoding]] = None + + +class ParameterBase(BaseModelWithConfig): + description: Optional[str] = None + required: Optional[bool] = None + deprecated: Optional[bool] = None + # Serialization rules for simple scenarios + style: Optional[str] = None + explode: Optional[bool] = None + allowReserved: Optional[bool] = None + schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema") + example: Optional[Any] = None + examples: Optional[Dict[str, Union[Example, Reference]]] = None + # Serialization rules for more complex scenarios + content: Optional[Dict[str, MediaType]] = None + + +class Parameter(ParameterBase): + name: str + in_: ParameterInType = Field(alias="in") + + +class Header(ParameterBase): + pass + + +class RequestBody(BaseModelWithConfig): + description: Optional[str] = None + content: Dict[str, MediaType] + required: Optional[bool] = None + + +class Link(BaseModelWithConfig): + operationRef: Optional[str] = None + operationId: Optional[str] = None + parameters: Optional[Dict[str, Union[Any, str]]] = None + requestBody: Optional[Union[Any, str]] = None + description: Optional[str] = None + server: Optional[Server] = None + + +class Response(BaseModelWithConfig): + description: str + headers: Optional[Dict[str, Union[Header, Reference]]] = None + content: Optional[Dict[str, MediaType]] = None + links: Optional[Dict[str, Union[Link, Reference]]] = None + + +class Operation(BaseModelWithConfig): + tags: Optional[List[str]] = None + summary: Optional[str] = None + description: Optional[str] = None + externalDocs: Optional[ExternalDocumentation] = None + operationId: Optional[str] = None + parameters: Optional[List[Union[Parameter, Reference]]] = None + requestBody: Optional[Union[RequestBody, Reference]] = None + # Using Any for Specification Extensions + responses: Optional[Dict[str, Union[Response, Any]]] = None + callbacks: Optional[Dict[str, Union[Dict[str, "PathItem"], Reference]]] = None + deprecated: Optional[bool] = None + security: Optional[List[Dict[str, List[str]]]] = None + servers: Optional[List[Server]] = None + + +class PathItem(BaseModelWithConfig): + ref: Optional[str] = Field(default=None, alias="$ref") + summary: Optional[str] = None + description: Optional[str] = None + get: Optional[Operation] = None + put: Optional[Operation] = None + post: Optional[Operation] = None + delete: Optional[Operation] = None + options: Optional[Operation] = None + head: Optional[Operation] = None + patch: Optional[Operation] = None + trace: Optional[Operation] = None + servers: Optional[List[Server]] = None + parameters: Optional[List[Union[Parameter, Reference]]] = None + + +class SecuritySchemeType(Enum): + apiKey = "apiKey" + http = "http" + oauth2 = "oauth2" + openIdConnect = "openIdConnect" + + +class SecurityBase(BaseModelWithConfig): + type_: SecuritySchemeType = Field(alias="type") + description: Optional[str] = None + + +class APIKeyIn(Enum): + query = "query" + header = "header" + cookie = "cookie" + + +class APIKey(SecurityBase): + type_: SecuritySchemeType = Field(default=SecuritySchemeType.apiKey, alias="type") + in_: APIKeyIn = Field(alias="in") + name: str + + +class HTTPBase(SecurityBase): + type_: SecuritySchemeType = Field(default=SecuritySchemeType.http, alias="type") + scheme: str + + +class HTTPBearer(HTTPBase): + scheme: Literal["bearer"] = "bearer" + bearerFormat: Optional[str] = None + + +class OAuthFlow(BaseModelWithConfig): + refreshUrl: Optional[str] = None + scopes: Dict[str, str] = {} + + +class OAuthFlowImplicit(OAuthFlow): + authorizationUrl: str + + +class OAuthFlowPassword(OAuthFlow): + tokenUrl: str + + +class OAuthFlowClientCredentials(OAuthFlow): + tokenUrl: str + + +class OAuthFlowAuthorizationCode(OAuthFlow): + authorizationUrl: str + tokenUrl: str + + +class OAuthFlows(BaseModelWithConfig): + implicit: Optional[OAuthFlowImplicit] = None + password: Optional[OAuthFlowPassword] = None + clientCredentials: Optional[OAuthFlowClientCredentials] = None + authorizationCode: Optional[OAuthFlowAuthorizationCode] = None + + +class OAuth2(SecurityBase): + type_: SecuritySchemeType = Field(default=SecuritySchemeType.oauth2, alias="type") + flows: OAuthFlows + + +class OpenIdConnect(SecurityBase): + type_: SecuritySchemeType = Field( + default=SecuritySchemeType.openIdConnect, alias="type" + ) + openIdConnectUrl: str + + +SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer] + + +class Components(BaseModelWithConfig): + schemas: Optional[Dict[str, Union[Schema, Reference]]] = None + responses: Optional[Dict[str, Union[Response, Reference]]] = None + parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None + examples: Optional[Dict[str, Union[Example, Reference]]] = None + requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None + headers: Optional[Dict[str, Union[Header, Reference]]] = None + securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None + links: Optional[Dict[str, Union[Link, Reference]]] = None + # Using Any for Specification Extensions + callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None + pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None + + +class Tag(BaseModelWithConfig): + name: str + description: Optional[str] = None + externalDocs: Optional[ExternalDocumentation] = None + + +class OpenAPI(BaseModelWithConfig): + openapi: str + info: Info + jsonSchemaDialect: Optional[str] = None + servers: Optional[List[Server]] = None + # Using Any for Specification Extensions + paths: Optional[Dict[str, Union[PathItem, Any]]] = None + webhooks: Optional[Dict[str, Union[PathItem, Reference]]] = None + components: Optional[Components] = None + security: Optional[List[Dict[str, List[str]]]] = None + tags: Optional[List[Tag]] = None + externalDocs: Optional[ExternalDocumentation] = None + + +_model_rebuild(Schema) +_model_rebuild(Operation) +_model_rebuild(Encoding) diff --git a/venv/lib/python3.11/site-packages/fastapi/openapi/utils.py b/venv/lib/python3.11/site-packages/fastapi/openapi/utils.py new file mode 100644 index 0000000..808646c --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/openapi/utils.py @@ -0,0 +1,569 @@ +import http.client +import inspect +import warnings +from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast + +from fastapi import routing +from fastapi._compat import ( + GenerateJsonSchema, + JsonSchemaValue, + ModelField, + Undefined, + get_compat_model_name_map, + get_definitions, + get_schema_from_model_field, + lenient_issubclass, +) +from fastapi.datastructures import DefaultPlaceholder +from fastapi.dependencies.models import Dependant +from fastapi.dependencies.utils import ( + _get_flat_fields_from_params, + get_flat_dependant, + get_flat_params, +) +from fastapi.encoders import jsonable_encoder +from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE +from fastapi.openapi.models import OpenAPI +from fastapi.params import Body, ParamTypes +from fastapi.responses import Response +from fastapi.types import ModelNameMap +from fastapi.utils import ( + deep_dict_update, + generate_operation_id_for_path, + is_body_allowed_for_status_code, +) +from pydantic import BaseModel +from starlette.responses import JSONResponse +from starlette.routing import BaseRoute +from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY +from typing_extensions import Literal + +validation_error_definition = { + "title": "ValidationError", + "type": "object", + "properties": { + "loc": { + "title": "Location", + "type": "array", + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, + }, + "msg": {"title": "Message", "type": "string"}, + "type": {"title": "Error Type", "type": "string"}, + }, + "required": ["loc", "msg", "type"], +} + +validation_error_response_definition = { + "title": "HTTPValidationError", + "type": "object", + "properties": { + "detail": { + "title": "Detail", + "type": "array", + "items": {"$ref": REF_PREFIX + "ValidationError"}, + } + }, +} + +status_code_ranges: Dict[str, str] = { + "1XX": "Information", + "2XX": "Success", + "3XX": "Redirection", + "4XX": "Client Error", + "5XX": "Server Error", + "DEFAULT": "Default Response", +} + + +def get_openapi_security_definitions( + flat_dependant: Dependant, +) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]: + security_definitions = {} + operation_security = [] + for security_requirement in flat_dependant.security_requirements: + security_definition = jsonable_encoder( + security_requirement.security_scheme.model, + by_alias=True, + exclude_none=True, + ) + security_name = security_requirement.security_scheme.scheme_name + security_definitions[security_name] = security_definition + operation_security.append({security_name: security_requirement.scopes}) + return security_definitions, operation_security + + +def _get_openapi_operation_parameters( + *, + dependant: Dependant, + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + field_mapping: Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + separate_input_output_schemas: bool = True, +) -> List[Dict[str, Any]]: + parameters = [] + flat_dependant = get_flat_dependant(dependant, skip_repeats=True) + path_params = _get_flat_fields_from_params(flat_dependant.path_params) + query_params = _get_flat_fields_from_params(flat_dependant.query_params) + header_params = _get_flat_fields_from_params(flat_dependant.header_params) + cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params) + parameter_groups = [ + (ParamTypes.path, path_params), + (ParamTypes.query, query_params), + (ParamTypes.header, header_params), + (ParamTypes.cookie, cookie_params), + ] + default_convert_underscores = True + if len(flat_dependant.header_params) == 1: + first_field = flat_dependant.header_params[0] + if lenient_issubclass(first_field.type_, BaseModel): + default_convert_underscores = getattr( + first_field.field_info, "convert_underscores", True + ) + for param_type, param_group in parameter_groups: + for param in param_group: + field_info = param.field_info + # field_info = cast(Param, field_info) + if not getattr(field_info, "include_in_schema", True): + continue + param_schema = get_schema_from_model_field( + field=param, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + name = param.alias + convert_underscores = getattr( + param.field_info, + "convert_underscores", + default_convert_underscores, + ) + if ( + param_type == ParamTypes.header + and param.alias == param.name + and convert_underscores + ): + name = param.name.replace("_", "-") + + parameter = { + "name": name, + "in": param_type.value, + "required": param.required, + "schema": param_schema, + } + if field_info.description: + parameter["description"] = field_info.description + openapi_examples = getattr(field_info, "openapi_examples", None) + example = getattr(field_info, "example", None) + if openapi_examples: + parameter["examples"] = jsonable_encoder(openapi_examples) + elif example != Undefined: + parameter["example"] = jsonable_encoder(example) + if getattr(field_info, "deprecated", None): + parameter["deprecated"] = True + parameters.append(parameter) + return parameters + + +def get_openapi_operation_request_body( + *, + body_field: Optional[ModelField], + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + field_mapping: Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + separate_input_output_schemas: bool = True, +) -> Optional[Dict[str, Any]]: + if not body_field: + return None + assert isinstance(body_field, ModelField) + body_schema = get_schema_from_model_field( + field=body_field, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + field_info = cast(Body, body_field.field_info) + request_media_type = field_info.media_type + required = body_field.required + request_body_oai: Dict[str, Any] = {} + if required: + request_body_oai["required"] = required + request_media_content: Dict[str, Any] = {"schema": body_schema} + if field_info.openapi_examples: + request_media_content["examples"] = jsonable_encoder( + field_info.openapi_examples + ) + elif field_info.example != Undefined: + request_media_content["example"] = jsonable_encoder(field_info.example) + request_body_oai["content"] = {request_media_type: request_media_content} + return request_body_oai + + +def generate_operation_id( + *, route: routing.APIRoute, method: str +) -> str: # pragma: nocover + warnings.warn( + "fastapi.openapi.utils.generate_operation_id() was deprecated, " + "it is not used internally, and will be removed soon", + DeprecationWarning, + stacklevel=2, + ) + if route.operation_id: + return route.operation_id + path: str = route.path_format + return generate_operation_id_for_path(name=route.name, path=path, method=method) + + +def generate_operation_summary(*, route: routing.APIRoute, method: str) -> str: + if route.summary: + return route.summary + return route.name.replace("_", " ").title() + + +def get_openapi_operation_metadata( + *, route: routing.APIRoute, method: str, operation_ids: Set[str] +) -> Dict[str, Any]: + operation: Dict[str, Any] = {} + if route.tags: + operation["tags"] = route.tags + operation["summary"] = generate_operation_summary(route=route, method=method) + if route.description: + operation["description"] = route.description + operation_id = route.operation_id or route.unique_id + if operation_id in operation_ids: + message = ( + f"Duplicate Operation ID {operation_id} for function " + + f"{route.endpoint.__name__}" + ) + file_name = getattr(route.endpoint, "__globals__", {}).get("__file__") + if file_name: + message += f" at {file_name}" + warnings.warn(message, stacklevel=1) + operation_ids.add(operation_id) + operation["operationId"] = operation_id + if route.deprecated: + operation["deprecated"] = route.deprecated + return operation + + +def get_openapi_path( + *, + route: routing.APIRoute, + operation_ids: Set[str], + schema_generator: GenerateJsonSchema, + model_name_map: ModelNameMap, + field_mapping: Dict[ + Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue + ], + separate_input_output_schemas: bool = True, +) -> Tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any]]: + path = {} + security_schemes: Dict[str, Any] = {} + definitions: Dict[str, Any] = {} + assert route.methods is not None, "Methods must be a list" + if isinstance(route.response_class, DefaultPlaceholder): + current_response_class: Type[Response] = route.response_class.value + else: + current_response_class = route.response_class + assert current_response_class, "A response class is needed to generate OpenAPI" + route_response_media_type: Optional[str] = current_response_class.media_type + if route.include_in_schema: + for method in route.methods: + operation = get_openapi_operation_metadata( + route=route, method=method, operation_ids=operation_ids + ) + parameters: List[Dict[str, Any]] = [] + flat_dependant = get_flat_dependant(route.dependant, skip_repeats=True) + security_definitions, operation_security = get_openapi_security_definitions( + flat_dependant=flat_dependant + ) + if operation_security: + operation.setdefault("security", []).extend(operation_security) + if security_definitions: + security_schemes.update(security_definitions) + operation_parameters = _get_openapi_operation_parameters( + dependant=route.dependant, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + parameters.extend(operation_parameters) + if parameters: + all_parameters = { + (param["in"], param["name"]): param for param in parameters + } + required_parameters = { + (param["in"], param["name"]): param + for param in parameters + if param.get("required") + } + # Make sure required definitions of the same parameter take precedence + # over non-required definitions + all_parameters.update(required_parameters) + operation["parameters"] = list(all_parameters.values()) + if method in METHODS_WITH_BODY: + request_body_oai = get_openapi_operation_request_body( + body_field=route.body_field, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + if request_body_oai: + operation["requestBody"] = request_body_oai + if route.callbacks: + callbacks = {} + for callback in route.callbacks: + if isinstance(callback, routing.APIRoute): + ( + cb_path, + cb_security_schemes, + cb_definitions, + ) = get_openapi_path( + route=callback, + operation_ids=operation_ids, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + callbacks[callback.name] = {callback.path: cb_path} + operation["callbacks"] = callbacks + if route.status_code is not None: + status_code = str(route.status_code) + else: + # It would probably make more sense for all response classes to have an + # explicit default status_code, and to extract it from them, instead of + # doing this inspection tricks, that would probably be in the future + # TODO: probably make status_code a default class attribute for all + # responses in Starlette + response_signature = inspect.signature(current_response_class.__init__) + status_code_param = response_signature.parameters.get("status_code") + if status_code_param is not None: + if isinstance(status_code_param.default, int): + status_code = str(status_code_param.default) + operation.setdefault("responses", {}).setdefault(status_code, {})[ + "description" + ] = route.response_description + if route_response_media_type and is_body_allowed_for_status_code( + route.status_code + ): + response_schema = {"type": "string"} + if lenient_issubclass(current_response_class, JSONResponse): + if route.response_field: + response_schema = get_schema_from_model_field( + field=route.response_field, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + else: + response_schema = {} + operation.setdefault("responses", {}).setdefault( + status_code, {} + ).setdefault("content", {}).setdefault(route_response_media_type, {})[ + "schema" + ] = response_schema + if route.responses: + operation_responses = operation.setdefault("responses", {}) + for ( + additional_status_code, + additional_response, + ) in route.responses.items(): + process_response = additional_response.copy() + process_response.pop("model", None) + status_code_key = str(additional_status_code).upper() + if status_code_key == "DEFAULT": + status_code_key = "default" + openapi_response = operation_responses.setdefault( + status_code_key, {} + ) + assert isinstance(process_response, dict), ( + "An additional response must be a dict" + ) + field = route.response_fields.get(additional_status_code) + additional_field_schema: Optional[Dict[str, Any]] = None + if field: + additional_field_schema = get_schema_from_model_field( + field=field, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + media_type = route_response_media_type or "application/json" + additional_schema = ( + process_response.setdefault("content", {}) + .setdefault(media_type, {}) + .setdefault("schema", {}) + ) + deep_dict_update(additional_schema, additional_field_schema) + status_text: Optional[str] = status_code_ranges.get( + str(additional_status_code).upper() + ) or http.client.responses.get(int(additional_status_code)) + description = ( + process_response.get("description") + or openapi_response.get("description") + or status_text + or "Additional Response" + ) + deep_dict_update(openapi_response, process_response) + openapi_response["description"] = description + http422 = str(HTTP_422_UNPROCESSABLE_ENTITY) + all_route_params = get_flat_params(route.dependant) + if (all_route_params or route.body_field) and not any( + status in operation["responses"] + for status in [http422, "4XX", "default"] + ): + operation["responses"][http422] = { + "description": "Validation Error", + "content": { + "application/json": { + "schema": {"$ref": REF_PREFIX + "HTTPValidationError"} + } + }, + } + if "ValidationError" not in definitions: + definitions.update( + { + "ValidationError": validation_error_definition, + "HTTPValidationError": validation_error_response_definition, + } + ) + if route.openapi_extra: + deep_dict_update(operation, route.openapi_extra) + path[method.lower()] = operation + return path, security_schemes, definitions + + +def get_fields_from_routes( + routes: Sequence[BaseRoute], +) -> List[ModelField]: + body_fields_from_routes: List[ModelField] = [] + responses_from_routes: List[ModelField] = [] + request_fields_from_routes: List[ModelField] = [] + callback_flat_models: List[ModelField] = [] + for route in routes: + if getattr(route, "include_in_schema", None) and isinstance( + route, routing.APIRoute + ): + if route.body_field: + assert isinstance(route.body_field, ModelField), ( + "A request body must be a Pydantic Field" + ) + body_fields_from_routes.append(route.body_field) + if route.response_field: + responses_from_routes.append(route.response_field) + if route.response_fields: + responses_from_routes.extend(route.response_fields.values()) + if route.callbacks: + callback_flat_models.extend(get_fields_from_routes(route.callbacks)) + params = get_flat_params(route.dependant) + request_fields_from_routes.extend(params) + + flat_models = callback_flat_models + list( + body_fields_from_routes + responses_from_routes + request_fields_from_routes + ) + return flat_models + + +def get_openapi( + *, + title: str, + version: str, + openapi_version: str = "3.1.0", + summary: Optional[str] = None, + description: Optional[str] = None, + routes: Sequence[BaseRoute], + webhooks: Optional[Sequence[BaseRoute]] = None, + tags: Optional[List[Dict[str, Any]]] = None, + servers: Optional[List[Dict[str, Union[str, Any]]]] = None, + terms_of_service: Optional[str] = None, + contact: Optional[Dict[str, Union[str, Any]]] = None, + license_info: Optional[Dict[str, Union[str, Any]]] = None, + separate_input_output_schemas: bool = True, +) -> Dict[str, Any]: + info: Dict[str, Any] = {"title": title, "version": version} + if summary: + info["summary"] = summary + if description: + info["description"] = description + if terms_of_service: + info["termsOfService"] = terms_of_service + if contact: + info["contact"] = contact + if license_info: + info["license"] = license_info + output: Dict[str, Any] = {"openapi": openapi_version, "info": info} + if servers: + output["servers"] = servers + components: Dict[str, Dict[str, Any]] = {} + paths: Dict[str, Dict[str, Any]] = {} + webhook_paths: Dict[str, Dict[str, Any]] = {} + operation_ids: Set[str] = set() + all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or [])) + model_name_map = get_compat_model_name_map(all_fields) + schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE) + field_mapping, definitions = get_definitions( + fields=all_fields, + schema_generator=schema_generator, + model_name_map=model_name_map, + separate_input_output_schemas=separate_input_output_schemas, + ) + for route in routes or []: + if isinstance(route, routing.APIRoute): + result = get_openapi_path( + route=route, + operation_ids=operation_ids, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + if result: + path, security_schemes, path_definitions = result + if path: + paths.setdefault(route.path_format, {}).update(path) + if security_schemes: + components.setdefault("securitySchemes", {}).update( + security_schemes + ) + if path_definitions: + definitions.update(path_definitions) + for webhook in webhooks or []: + if isinstance(webhook, routing.APIRoute): + result = get_openapi_path( + route=webhook, + operation_ids=operation_ids, + schema_generator=schema_generator, + model_name_map=model_name_map, + field_mapping=field_mapping, + separate_input_output_schemas=separate_input_output_schemas, + ) + if result: + path, security_schemes, path_definitions = result + if path: + webhook_paths.setdefault(webhook.path_format, {}).update(path) + if security_schemes: + components.setdefault("securitySchemes", {}).update( + security_schemes + ) + if path_definitions: + definitions.update(path_definitions) + if definitions: + components["schemas"] = {k: definitions[k] for k in sorted(definitions)} + if components: + output["components"] = components + output["paths"] = paths + if webhook_paths: + output["webhooks"] = webhook_paths + if tags: + output["tags"] = tags + return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore diff --git a/venv/lib/python3.11/site-packages/fastapi/param_functions.py b/venv/lib/python3.11/site-packages/fastapi/param_functions.py new file mode 100644 index 0000000..b362162 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/param_functions.py @@ -0,0 +1,2360 @@ +from typing import Any, Callable, Dict, List, Optional, Sequence, Union + +from fastapi import params +from fastapi._compat import Undefined +from fastapi.openapi.models import Example +from typing_extensions import Annotated, Doc, deprecated + +_Unset: Any = Undefined + + +def Path( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = ..., + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + """ + Declare a path parameter for a *path operation*. + + Read more about it in the + [FastAPI docs for Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/). + + ```python + from typing import Annotated + + from fastapi import FastAPI, Path + + app = FastAPI() + + + @app.get("/items/{item_id}") + async def read_items( + item_id: Annotated[int, Path(title="The ID of the item to get")], + ): + return {"item_id": item_id} + ``` + """ + return params.Path( + default=default, + default_factory=default_factory, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def Query( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + """ + ), + ] = Undefined, + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + return params.Query( + default=default, + default_factory=default_factory, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def Header( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + """ + ), + ] = Undefined, + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + convert_underscores: Annotated[ + bool, + Doc( + """ + Automatically convert underscores to hyphens in the parameter field name. + + Read more about it in the + [FastAPI docs for Header Parameters](https://fastapi.tiangolo.com/tutorial/header-params/#automatic-conversion) + """ + ), + ] = True, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + return params.Header( + default=default, + default_factory=default_factory, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + convert_underscores=convert_underscores, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def Cookie( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + """ + ), + ] = Undefined, + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + return params.Cookie( + default=default, + default_factory=default_factory, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def Body( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + """ + ), + ] = Undefined, + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + embed: Annotated[ + Union[bool, None], + Doc( + """ + When `embed` is `True`, the parameter will be expected in a JSON body as a + key instead of being the JSON body itself. + + This happens automatically when more than one `Body` parameter is declared. + + Read more about it in the + [FastAPI docs for Body - Multiple Parameters](https://fastapi.tiangolo.com/tutorial/body-multiple-params/#embed-a-single-body-parameter). + """ + ), + ] = None, + media_type: Annotated[ + str, + Doc( + """ + The media type of this parameter field. Changing it would affect the + generated OpenAPI, but currently it doesn't affect the parsing of the data. + """ + ), + ] = "application/json", + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + return params.Body( + default=default, + default_factory=default_factory, + embed=embed, + media_type=media_type, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def Form( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + """ + ), + ] = Undefined, + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + media_type: Annotated[ + str, + Doc( + """ + The media type of this parameter field. Changing it would affect the + generated OpenAPI, but currently it doesn't affect the parsing of the data. + """ + ), + ] = "application/x-www-form-urlencoded", + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + return params.Form( + default=default, + default_factory=default_factory, + media_type=media_type, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def File( # noqa: N802 + default: Annotated[ + Any, + Doc( + """ + Default value if the parameter field is not set. + """ + ), + ] = Undefined, + *, + default_factory: Annotated[ + Union[Callable[[], Any], None], + Doc( + """ + A callable to generate the default value. + + This doesn't affect `Path` parameters as the value is always required. + The parameter is available only for compatibility. + """ + ), + ] = _Unset, + media_type: Annotated[ + str, + Doc( + """ + The media type of this parameter field. Changing it would affect the + generated OpenAPI, but currently it doesn't affect the parsing of the data. + """ + ), + ] = "multipart/form-data", + alias: Annotated[ + Optional[str], + Doc( + """ + An alternative name for the parameter field. + + This will be used to extract the data and for the generated OpenAPI. + It is particularly useful when you can't use the name you want because it + is a Python reserved keyword or similar. + """ + ), + ] = None, + alias_priority: Annotated[ + Union[int, None], + Doc( + """ + Priority of the alias. This affects whether an alias generator is used. + """ + ), + ] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Whitelist' validation step. The parameter field will be the single one + allowed by the alias or set of aliases defined. + """ + ), + ] = None, + serialization_alias: Annotated[ + Union[str, None], + Doc( + """ + 'Blacklist' validation step. The vanilla parameter field will be the + single one of the alias' or set of aliases' fields and all the other + fields will be ignored at serialization time. + """ + ), + ] = None, + title: Annotated[ + Optional[str], + Doc( + """ + Human-readable title. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Human-readable description. + """ + ), + ] = None, + gt: Annotated[ + Optional[float], + Doc( + """ + Greater than. If set, value must be greater than this. Only applicable to + numbers. + """ + ), + ] = None, + ge: Annotated[ + Optional[float], + Doc( + """ + Greater than or equal. If set, value must be greater than or equal to + this. Only applicable to numbers. + """ + ), + ] = None, + lt: Annotated[ + Optional[float], + Doc( + """ + Less than. If set, value must be less than this. Only applicable to numbers. + """ + ), + ] = None, + le: Annotated[ + Optional[float], + Doc( + """ + Less than or equal. If set, value must be less than or equal to this. + Only applicable to numbers. + """ + ), + ] = None, + min_length: Annotated[ + Optional[int], + Doc( + """ + Minimum length for strings. + """ + ), + ] = None, + max_length: Annotated[ + Optional[int], + Doc( + """ + Maximum length for strings. + """ + ), + ] = None, + pattern: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + ] = None, + regex: Annotated[ + Optional[str], + Doc( + """ + RegEx pattern for strings. + """ + ), + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Annotated[ + Union[str, None], + Doc( + """ + Parameter field name for discriminating the type in a tagged union. + """ + ), + ] = None, + strict: Annotated[ + Union[bool, None], + Doc( + """ + If `True`, strict validation is applied to the field. + """ + ), + ] = _Unset, + multiple_of: Annotated[ + Union[float, None], + Doc( + """ + Value must be a multiple of this. Only applicable to numbers. + """ + ), + ] = _Unset, + allow_inf_nan: Annotated[ + Union[bool, None], + Doc( + """ + Allow `inf`, `-inf`, `nan`. Only applicable to numbers. + """ + ), + ] = _Unset, + max_digits: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of allow digits for strings. + """ + ), + ] = _Unset, + decimal_places: Annotated[ + Union[int, None], + Doc( + """ + Maximum number of decimal places allowed for numbers. + """ + ), + ] = _Unset, + examples: Annotated[ + Optional[List[Any]], + Doc( + """ + Example values for this field. + """ + ), + ] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Annotated[ + Optional[Dict[str, Example]], + Doc( + """ + OpenAPI-specific examples. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Swagger UI (that provides the `/docs` interface) has better support for the + OpenAPI-specific examples than the JSON Schema `examples`, that's the main + use case for this. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter). + """ + ), + ] = None, + deprecated: Annotated[ + Union[deprecated, str, bool, None], + Doc( + """ + Mark this parameter field as deprecated. + + It will affect the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) this parameter field in the generated OpenAPI. + You probably don't need it, but it's available. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + json_schema_extra: Annotated[ + Union[Dict[str, Any], None], + Doc( + """ + Any additional JSON schema data. + """ + ), + ] = None, + **extra: Annotated[ + Any, + Doc( + """ + Include extra fields used by the JSON Schema. + """ + ), + deprecated( + """ + The `extra` kwargs is deprecated. Use `json_schema_extra` instead. + """ + ), + ], +) -> Any: + return params.File( + default=default, + default_factory=default_factory, + media_type=media_type, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + example=example, + examples=examples, + openapi_examples=openapi_examples, + deprecated=deprecated, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +def Depends( # noqa: N802 + dependency: Annotated[ + Optional[Callable[..., Any]], + Doc( + """ + A "dependable" callable (like a function). + + Don't call it directly, FastAPI will call it for you, just pass the object + directly. + """ + ), + ] = None, + *, + use_cache: Annotated[ + bool, + Doc( + """ + By default, after a dependency is called the first time in a request, if + the dependency is declared again for the rest of the request (for example + if the dependency is needed by several dependencies), the value will be + re-used for the rest of the request. + + Set `use_cache` to `False` to disable this behavior and ensure the + dependency is called again (if declared more than once) in the same request. + """ + ), + ] = True, +) -> Any: + """ + Declare a FastAPI dependency. + + It takes a single "dependable" callable (like a function). + + Don't call it directly, FastAPI will call it for you. + + Read more about it in the + [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/). + + **Example** + + ```python + from typing import Annotated + + from fastapi import Depends, FastAPI + + app = FastAPI() + + + async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100): + return {"q": q, "skip": skip, "limit": limit} + + + @app.get("/items/") + async def read_items(commons: Annotated[dict, Depends(common_parameters)]): + return commons + ``` + """ + return params.Depends(dependency=dependency, use_cache=use_cache) + + +def Security( # noqa: N802 + dependency: Annotated[ + Optional[Callable[..., Any]], + Doc( + """ + A "dependable" callable (like a function). + + Don't call it directly, FastAPI will call it for you, just pass the object + directly. + """ + ), + ] = None, + *, + scopes: Annotated[ + Optional[Sequence[str]], + Doc( + """ + OAuth2 scopes required for the *path operation* that uses this Security + dependency. + + The term "scope" comes from the OAuth2 specification, it seems to be + intentionally vague and interpretable. It normally refers to permissions, + in cases to roles. + + These scopes are integrated with OpenAPI (and the API docs at `/docs`). + So they are visible in the OpenAPI specification. + ) + """ + ), + ] = None, + use_cache: Annotated[ + bool, + Doc( + """ + By default, after a dependency is called the first time in a request, if + the dependency is declared again for the rest of the request (for example + if the dependency is needed by several dependencies), the value will be + re-used for the rest of the request. + + Set `use_cache` to `False` to disable this behavior and ensure the + dependency is called again (if declared more than once) in the same request. + """ + ), + ] = True, +) -> Any: + """ + Declare a FastAPI Security dependency. + + The only difference with a regular dependency is that it can declare OAuth2 + scopes that will be integrated with OpenAPI and the automatic UI docs (by default + at `/docs`). + + It takes a single "dependable" callable (like a function). + + Don't call it directly, FastAPI will call it for you. + + Read more about it in the + [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/) and + in the + [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/). + + **Example** + + ```python + from typing import Annotated + + from fastapi import Security, FastAPI + + from .db import User + from .security import get_current_active_user + + app = FastAPI() + + @app.get("/users/me/items/") + async def read_own_items( + current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])] + ): + return [{"item_id": "Foo", "owner": current_user.username}] + ``` + """ + return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache) diff --git a/venv/lib/python3.11/site-packages/fastapi/params.py b/venv/lib/python3.11/site-packages/fastapi/params.py new file mode 100644 index 0000000..8f5601d --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/params.py @@ -0,0 +1,786 @@ +import warnings +from enum import Enum +from typing import Any, Callable, Dict, List, Optional, Sequence, Union + +from fastapi.openapi.models import Example +from pydantic.fields import FieldInfo +from typing_extensions import Annotated, deprecated + +from ._compat import ( + PYDANTIC_V2, + PYDANTIC_VERSION_MINOR_TUPLE, + Undefined, +) + +_Unset: Any = Undefined + + +class ParamTypes(Enum): + query = "query" + header = "header" + path = "path" + cookie = "cookie" + + +class Param(FieldInfo): + in_: ParamTypes + + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + if example is not _Unset: + warnings.warn( + "`example` has been deprecated, please use `examples` instead", + category=DeprecationWarning, + stacklevel=4, + ) + self.example = example + self.include_in_schema = include_in_schema + self.openapi_examples = openapi_examples + kwargs = dict( + default=default, + default_factory=default_factory, + alias=alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + discriminator=discriminator, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + **extra, + ) + if examples is not None: + kwargs["examples"] = examples + if regex is not None: + warnings.warn( + "`regex` has been deprecated, please use `pattern` instead", + category=DeprecationWarning, + stacklevel=4, + ) + current_json_schema_extra = json_schema_extra or extra + if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7): + self.deprecated = deprecated + else: + kwargs["deprecated"] = deprecated + if PYDANTIC_V2: + kwargs.update( + { + "annotation": annotation, + "alias_priority": alias_priority, + "validation_alias": validation_alias, + "serialization_alias": serialization_alias, + "strict": strict, + "json_schema_extra": current_json_schema_extra, + } + ) + kwargs["pattern"] = pattern or regex + else: + kwargs["regex"] = pattern or regex + kwargs.update(**current_json_schema_extra) + use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset} + + super().__init__(**use_kwargs) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.default})" + + +class Path(Param): + in_ = ParamTypes.path + + def __init__( + self, + default: Any = ..., + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + assert default is ..., "Path parameters cannot have a default value" + self.in_ = self.in_ + super().__init__( + default=default, + default_factory=default_factory, + annotation=annotation, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + deprecated=deprecated, + example=example, + examples=examples, + openapi_examples=openapi_examples, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +class Query(Param): + in_ = ParamTypes.query + + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + super().__init__( + default=default, + default_factory=default_factory, + annotation=annotation, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + deprecated=deprecated, + example=example, + examples=examples, + openapi_examples=openapi_examples, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +class Header(Param): + in_ = ParamTypes.header + + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + convert_underscores: bool = True, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + self.convert_underscores = convert_underscores + super().__init__( + default=default, + default_factory=default_factory, + annotation=annotation, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + deprecated=deprecated, + example=example, + examples=examples, + openapi_examples=openapi_examples, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +class Cookie(Param): + in_ = ParamTypes.cookie + + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + super().__init__( + default=default, + default_factory=default_factory, + annotation=annotation, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + deprecated=deprecated, + example=example, + examples=examples, + openapi_examples=openapi_examples, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +class Body(FieldInfo): + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + embed: Union[bool, None] = None, + media_type: str = "application/json", + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + self.embed = embed + self.media_type = media_type + if example is not _Unset: + warnings.warn( + "`example` has been deprecated, please use `examples` instead", + category=DeprecationWarning, + stacklevel=4, + ) + self.example = example + self.include_in_schema = include_in_schema + self.openapi_examples = openapi_examples + kwargs = dict( + default=default, + default_factory=default_factory, + alias=alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + discriminator=discriminator, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + **extra, + ) + if examples is not None: + kwargs["examples"] = examples + if regex is not None: + warnings.warn( + "`regex` has been deprecated, please use `pattern` instead", + category=DeprecationWarning, + stacklevel=4, + ) + current_json_schema_extra = json_schema_extra or extra + if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7): + self.deprecated = deprecated + else: + kwargs["deprecated"] = deprecated + if PYDANTIC_V2: + kwargs.update( + { + "annotation": annotation, + "alias_priority": alias_priority, + "validation_alias": validation_alias, + "serialization_alias": serialization_alias, + "strict": strict, + "json_schema_extra": current_json_schema_extra, + } + ) + kwargs["pattern"] = pattern or regex + else: + kwargs["regex"] = pattern or regex + kwargs.update(**current_json_schema_extra) + + use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset} + + super().__init__(**use_kwargs) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.default})" + + +class Form(Body): + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + media_type: str = "application/x-www-form-urlencoded", + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + super().__init__( + default=default, + default_factory=default_factory, + annotation=annotation, + media_type=media_type, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + deprecated=deprecated, + example=example, + examples=examples, + openapi_examples=openapi_examples, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +class File(Form): + def __init__( + self, + default: Any = Undefined, + *, + default_factory: Union[Callable[[], Any], None] = _Unset, + annotation: Optional[Any] = None, + media_type: str = "multipart/form-data", + alias: Optional[str] = None, + alias_priority: Union[int, None] = _Unset, + # TODO: update when deprecating Pydantic v1, import these types + # validation_alias: str | AliasPath | AliasChoices | None + validation_alias: Union[str, None] = None, + serialization_alias: Union[str, None] = None, + title: Optional[str] = None, + description: Optional[str] = None, + gt: Optional[float] = None, + ge: Optional[float] = None, + lt: Optional[float] = None, + le: Optional[float] = None, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + pattern: Optional[str] = None, + regex: Annotated[ + Optional[str], + deprecated( + "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead." + ), + ] = None, + discriminator: Union[str, None] = None, + strict: Union[bool, None] = _Unset, + multiple_of: Union[float, None] = _Unset, + allow_inf_nan: Union[bool, None] = _Unset, + max_digits: Union[int, None] = _Unset, + decimal_places: Union[int, None] = _Unset, + examples: Optional[List[Any]] = None, + example: Annotated[ + Optional[Any], + deprecated( + "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, " + "although still supported. Use examples instead." + ), + ] = _Unset, + openapi_examples: Optional[Dict[str, Example]] = None, + deprecated: Union[deprecated, str, bool, None] = None, + include_in_schema: bool = True, + json_schema_extra: Union[Dict[str, Any], None] = None, + **extra: Any, + ): + super().__init__( + default=default, + default_factory=default_factory, + annotation=annotation, + media_type=media_type, + alias=alias, + alias_priority=alias_priority, + validation_alias=validation_alias, + serialization_alias=serialization_alias, + title=title, + description=description, + gt=gt, + ge=ge, + lt=lt, + le=le, + min_length=min_length, + max_length=max_length, + pattern=pattern, + regex=regex, + discriminator=discriminator, + strict=strict, + multiple_of=multiple_of, + allow_inf_nan=allow_inf_nan, + max_digits=max_digits, + decimal_places=decimal_places, + deprecated=deprecated, + example=example, + examples=examples, + openapi_examples=openapi_examples, + include_in_schema=include_in_schema, + json_schema_extra=json_schema_extra, + **extra, + ) + + +class Depends: + def __init__( + self, dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True + ): + self.dependency = dependency + self.use_cache = use_cache + + def __repr__(self) -> str: + attr = getattr(self.dependency, "__name__", type(self.dependency).__name__) + cache = "" if self.use_cache else ", use_cache=False" + return f"{self.__class__.__name__}({attr}{cache})" + + +class Security(Depends): + def __init__( + self, + dependency: Optional[Callable[..., Any]] = None, + *, + scopes: Optional[Sequence[str]] = None, + use_cache: bool = True, + ): + super().__init__(dependency=dependency, use_cache=use_cache) + self.scopes = scopes or [] diff --git a/venv/lib/python3.11/site-packages/fastapi/py.typed b/venv/lib/python3.11/site-packages/fastapi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/fastapi/requests.py b/venv/lib/python3.11/site-packages/fastapi/requests.py new file mode 100644 index 0000000..d16552c --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/requests.py @@ -0,0 +1,2 @@ +from starlette.requests import HTTPConnection as HTTPConnection # noqa: F401 +from starlette.requests import Request as Request # noqa: F401 diff --git a/venv/lib/python3.11/site-packages/fastapi/responses.py b/venv/lib/python3.11/site-packages/fastapi/responses.py new file mode 100644 index 0000000..6c8db6f --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/responses.py @@ -0,0 +1,48 @@ +from typing import Any + +from starlette.responses import FileResponse as FileResponse # noqa +from starlette.responses import HTMLResponse as HTMLResponse # noqa +from starlette.responses import JSONResponse as JSONResponse # noqa +from starlette.responses import PlainTextResponse as PlainTextResponse # noqa +from starlette.responses import RedirectResponse as RedirectResponse # noqa +from starlette.responses import Response as Response # noqa +from starlette.responses import StreamingResponse as StreamingResponse # noqa + +try: + import ujson +except ImportError: # pragma: nocover + ujson = None # type: ignore + + +try: + import orjson +except ImportError: # pragma: nocover + orjson = None # type: ignore + + +class UJSONResponse(JSONResponse): + """ + JSON response using the high-performance ujson library to serialize data to JSON. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/). + """ + + def render(self, content: Any) -> bytes: + assert ujson is not None, "ujson must be installed to use UJSONResponse" + return ujson.dumps(content, ensure_ascii=False).encode("utf-8") + + +class ORJSONResponse(JSONResponse): + """ + JSON response using the high-performance orjson library to serialize data to JSON. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/). + """ + + def render(self, content: Any) -> bytes: + assert orjson is not None, "orjson must be installed to use ORJSONResponse" + return orjson.dumps( + content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY + ) diff --git a/venv/lib/python3.11/site-packages/fastapi/routing.py b/venv/lib/python3.11/site-packages/fastapi/routing.py new file mode 100644 index 0000000..457481e --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/routing.py @@ -0,0 +1,4439 @@ +import asyncio +import dataclasses +import email.message +import inspect +import json +from contextlib import AsyncExitStack, asynccontextmanager +from enum import Enum, IntEnum +from typing import ( + Any, + AsyncIterator, + Callable, + Coroutine, + Dict, + List, + Mapping, + Optional, + Sequence, + Set, + Tuple, + Type, + Union, +) + +from fastapi import params +from fastapi._compat import ( + ModelField, + Undefined, + _get_model_config, + _model_dump, + _normalize_errors, + lenient_issubclass, +) +from fastapi.datastructures import Default, DefaultPlaceholder +from fastapi.dependencies.models import Dependant +from fastapi.dependencies.utils import ( + _should_embed_body_fields, + get_body_field, + get_dependant, + get_flat_dependant, + get_parameterless_sub_dependant, + get_typed_return_annotation, + solve_dependencies, +) +from fastapi.encoders import jsonable_encoder +from fastapi.exceptions import ( + FastAPIError, + RequestValidationError, + ResponseValidationError, + WebSocketRequestValidationError, +) +from fastapi.types import DecoratedCallable, IncEx +from fastapi.utils import ( + create_cloned_field, + create_model_field, + generate_unique_id, + get_value_or_default, + is_body_allowed_for_status_code, +) +from pydantic import BaseModel +from starlette import routing +from starlette.concurrency import run_in_threadpool +from starlette.exceptions import HTTPException +from starlette.requests import Request +from starlette.responses import JSONResponse, Response +from starlette.routing import ( + BaseRoute, + Match, + compile_path, + get_name, + request_response, + websocket_session, +) +from starlette.routing import Mount as Mount # noqa +from starlette.types import AppType, ASGIApp, Lifespan, Scope +from starlette.websockets import WebSocket +from typing_extensions import Annotated, Doc, deprecated + + +def _prepare_response_content( + res: Any, + *, + exclude_unset: bool, + exclude_defaults: bool = False, + exclude_none: bool = False, +) -> Any: + if isinstance(res, BaseModel): + read_with_orm_mode = getattr(_get_model_config(res), "read_with_orm_mode", None) + if read_with_orm_mode: + # Let from_orm extract the data from this model instead of converting + # it now to a dict. + # Otherwise, there's no way to extract lazy data that requires attribute + # access instead of dict iteration, e.g. lazy relationships. + return res + return _model_dump( + res, + by_alias=True, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + elif isinstance(res, list): + return [ + _prepare_response_content( + item, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + for item in res + ] + elif isinstance(res, dict): + return { + k: _prepare_response_content( + v, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + for k, v in res.items() + } + elif dataclasses.is_dataclass(res): + return dataclasses.asdict(res) + return res + + +def _merge_lifespan_context( + original_context: Lifespan[Any], nested_context: Lifespan[Any] +) -> Lifespan[Any]: + @asynccontextmanager + async def merged_lifespan( + app: AppType, + ) -> AsyncIterator[Optional[Mapping[str, Any]]]: + async with original_context(app) as maybe_original_state: + async with nested_context(app) as maybe_nested_state: + if maybe_nested_state is None and maybe_original_state is None: + yield None # old ASGI compatibility + else: + yield {**(maybe_nested_state or {}), **(maybe_original_state or {})} + + return merged_lifespan # type: ignore[return-value] + + +async def serialize_response( + *, + field: Optional[ModelField] = None, + response_content: Any, + include: Optional[IncEx] = None, + exclude: Optional[IncEx] = None, + by_alias: bool = True, + exclude_unset: bool = False, + exclude_defaults: bool = False, + exclude_none: bool = False, + is_coroutine: bool = True, +) -> Any: + if field: + errors = [] + if not hasattr(field, "serialize"): + # pydantic v1 + response_content = _prepare_response_content( + response_content, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + if is_coroutine: + value, errors_ = field.validate(response_content, {}, loc=("response",)) + else: + value, errors_ = await run_in_threadpool( + field.validate, response_content, {}, loc=("response",) + ) + if isinstance(errors_, list): + errors.extend(errors_) + elif errors_: + errors.append(errors_) + if errors: + raise ResponseValidationError( + errors=_normalize_errors(errors), body=response_content + ) + + if hasattr(field, "serialize"): + return field.serialize( + value, + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + + return jsonable_encoder( + value, + include=include, + exclude=exclude, + by_alias=by_alias, + exclude_unset=exclude_unset, + exclude_defaults=exclude_defaults, + exclude_none=exclude_none, + ) + else: + return jsonable_encoder(response_content) + + +async def run_endpoint_function( + *, dependant: Dependant, values: Dict[str, Any], is_coroutine: bool +) -> Any: + # Only called by get_request_handler. Has been split into its own function to + # facilitate profiling endpoints, since inner functions are harder to profile. + assert dependant.call is not None, "dependant.call must be a function" + + if is_coroutine: + return await dependant.call(**values) + else: + return await run_in_threadpool(dependant.call, **values) + + +def get_request_handler( + dependant: Dependant, + body_field: Optional[ModelField] = None, + status_code: Optional[int] = None, + response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse), + response_field: Optional[ModelField] = None, + response_model_include: Optional[IncEx] = None, + response_model_exclude: Optional[IncEx] = None, + response_model_by_alias: bool = True, + response_model_exclude_unset: bool = False, + response_model_exclude_defaults: bool = False, + response_model_exclude_none: bool = False, + dependency_overrides_provider: Optional[Any] = None, + embed_body_fields: bool = False, +) -> Callable[[Request], Coroutine[Any, Any, Response]]: + assert dependant.call is not None, "dependant.call must be a function" + is_coroutine = asyncio.iscoroutinefunction(dependant.call) + is_body_form = body_field and isinstance(body_field.field_info, params.Form) + if isinstance(response_class, DefaultPlaceholder): + actual_response_class: Type[Response] = response_class.value + else: + actual_response_class = response_class + + async def app(request: Request) -> Response: + response: Union[Response, None] = None + async with AsyncExitStack() as file_stack: + try: + body: Any = None + if body_field: + if is_body_form: + body = await request.form() + file_stack.push_async_callback(body.close) + else: + body_bytes = await request.body() + if body_bytes: + json_body: Any = Undefined + content_type_value = request.headers.get("content-type") + if not content_type_value: + json_body = await request.json() + else: + message = email.message.Message() + message["content-type"] = content_type_value + if message.get_content_maintype() == "application": + subtype = message.get_content_subtype() + if subtype == "json" or subtype.endswith("+json"): + json_body = await request.json() + if json_body != Undefined: + body = json_body + else: + body = body_bytes + except json.JSONDecodeError as e: + validation_error = RequestValidationError( + [ + { + "type": "json_invalid", + "loc": ("body", e.pos), + "msg": "JSON decode error", + "input": {}, + "ctx": {"error": e.msg}, + } + ], + body=e.doc, + ) + raise validation_error from e + except HTTPException: + # If a middleware raises an HTTPException, it should be raised again + raise + except Exception as e: + http_error = HTTPException( + status_code=400, detail="There was an error parsing the body" + ) + raise http_error from e + errors: List[Any] = [] + async with AsyncExitStack() as async_exit_stack: + solved_result = await solve_dependencies( + request=request, + dependant=dependant, + body=body, + dependency_overrides_provider=dependency_overrides_provider, + async_exit_stack=async_exit_stack, + embed_body_fields=embed_body_fields, + ) + errors = solved_result.errors + if not errors: + raw_response = await run_endpoint_function( + dependant=dependant, + values=solved_result.values, + is_coroutine=is_coroutine, + ) + if isinstance(raw_response, Response): + if raw_response.background is None: + raw_response.background = solved_result.background_tasks + response = raw_response + else: + response_args: Dict[str, Any] = { + "background": solved_result.background_tasks + } + # If status_code was set, use it, otherwise use the default from the + # response class, in the case of redirect it's 307 + current_status_code = ( + status_code + if status_code + else solved_result.response.status_code + ) + if current_status_code is not None: + response_args["status_code"] = current_status_code + if solved_result.response.status_code: + response_args["status_code"] = ( + solved_result.response.status_code + ) + content = await serialize_response( + field=response_field, + response_content=raw_response, + include=response_model_include, + exclude=response_model_exclude, + by_alias=response_model_by_alias, + exclude_unset=response_model_exclude_unset, + exclude_defaults=response_model_exclude_defaults, + exclude_none=response_model_exclude_none, + is_coroutine=is_coroutine, + ) + response = actual_response_class(content, **response_args) + if not is_body_allowed_for_status_code(response.status_code): + response.body = b"" + response.headers.raw.extend(solved_result.response.headers.raw) + if errors: + validation_error = RequestValidationError( + _normalize_errors(errors), body=body + ) + raise validation_error + if response is None: + raise FastAPIError( + "No response object was returned. There's a high chance that the " + "application code is raising an exception and a dependency with yield " + "has a block with a bare except, or a block with except Exception, " + "and is not raising the exception again. Read more about it in the " + "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except" + ) + return response + + return app + + +def get_websocket_app( + dependant: Dependant, + dependency_overrides_provider: Optional[Any] = None, + embed_body_fields: bool = False, +) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]: + async def app(websocket: WebSocket) -> None: + async with AsyncExitStack() as async_exit_stack: + # TODO: remove this scope later, after a few releases + # This scope fastapi_astack is no longer used by FastAPI, kept for + # compatibility, just in case + websocket.scope["fastapi_astack"] = async_exit_stack + solved_result = await solve_dependencies( + request=websocket, + dependant=dependant, + dependency_overrides_provider=dependency_overrides_provider, + async_exit_stack=async_exit_stack, + embed_body_fields=embed_body_fields, + ) + if solved_result.errors: + raise WebSocketRequestValidationError( + _normalize_errors(solved_result.errors) + ) + assert dependant.call is not None, "dependant.call must be a function" + await dependant.call(**solved_result.values) + + return app + + +class APIWebSocketRoute(routing.WebSocketRoute): + def __init__( + self, + path: str, + endpoint: Callable[..., Any], + *, + name: Optional[str] = None, + dependencies: Optional[Sequence[params.Depends]] = None, + dependency_overrides_provider: Optional[Any] = None, + ) -> None: + self.path = path + self.endpoint = endpoint + self.name = get_name(endpoint) if name is None else name + self.dependencies = list(dependencies or []) + self.path_regex, self.path_format, self.param_convertors = compile_path(path) + self.dependant = get_dependant(path=self.path_format, call=self.endpoint) + for depends in self.dependencies[::-1]: + self.dependant.dependencies.insert( + 0, + get_parameterless_sub_dependant(depends=depends, path=self.path_format), + ) + self._flat_dependant = get_flat_dependant(self.dependant) + self._embed_body_fields = _should_embed_body_fields( + self._flat_dependant.body_params + ) + self.app = websocket_session( + get_websocket_app( + dependant=self.dependant, + dependency_overrides_provider=dependency_overrides_provider, + embed_body_fields=self._embed_body_fields, + ) + ) + + def matches(self, scope: Scope) -> Tuple[Match, Scope]: + match, child_scope = super().matches(scope) + if match != Match.NONE: + child_scope["route"] = self + return match, child_scope + + +class APIRoute(routing.Route): + def __init__( + self, + path: str, + endpoint: Callable[..., Any], + *, + response_model: Any = Default(None), + status_code: Optional[int] = None, + tags: Optional[List[Union[str, Enum]]] = None, + dependencies: Optional[Sequence[params.Depends]] = None, + summary: Optional[str] = None, + description: Optional[str] = None, + response_description: str = "Successful Response", + responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, + deprecated: Optional[bool] = None, + name: Optional[str] = None, + methods: Optional[Union[Set[str], List[str]]] = None, + operation_id: Optional[str] = None, + response_model_include: Optional[IncEx] = None, + response_model_exclude: Optional[IncEx] = None, + response_model_by_alias: bool = True, + response_model_exclude_unset: bool = False, + response_model_exclude_defaults: bool = False, + response_model_exclude_none: bool = False, + include_in_schema: bool = True, + response_class: Union[Type[Response], DefaultPlaceholder] = Default( + JSONResponse + ), + dependency_overrides_provider: Optional[Any] = None, + callbacks: Optional[List[BaseRoute]] = None, + openapi_extra: Optional[Dict[str, Any]] = None, + generate_unique_id_function: Union[ + Callable[["APIRoute"], str], DefaultPlaceholder + ] = Default(generate_unique_id), + ) -> None: + self.path = path + self.endpoint = endpoint + if isinstance(response_model, DefaultPlaceholder): + return_annotation = get_typed_return_annotation(endpoint) + if lenient_issubclass(return_annotation, Response): + response_model = None + else: + response_model = return_annotation + self.response_model = response_model + self.summary = summary + self.response_description = response_description + self.deprecated = deprecated + self.operation_id = operation_id + self.response_model_include = response_model_include + self.response_model_exclude = response_model_exclude + self.response_model_by_alias = response_model_by_alias + self.response_model_exclude_unset = response_model_exclude_unset + self.response_model_exclude_defaults = response_model_exclude_defaults + self.response_model_exclude_none = response_model_exclude_none + self.include_in_schema = include_in_schema + self.response_class = response_class + self.dependency_overrides_provider = dependency_overrides_provider + self.callbacks = callbacks + self.openapi_extra = openapi_extra + self.generate_unique_id_function = generate_unique_id_function + self.tags = tags or [] + self.responses = responses or {} + self.name = get_name(endpoint) if name is None else name + self.path_regex, self.path_format, self.param_convertors = compile_path(path) + if methods is None: + methods = ["GET"] + self.methods: Set[str] = {method.upper() for method in methods} + if isinstance(generate_unique_id_function, DefaultPlaceholder): + current_generate_unique_id: Callable[[APIRoute], str] = ( + generate_unique_id_function.value + ) + else: + current_generate_unique_id = generate_unique_id_function + self.unique_id = self.operation_id or current_generate_unique_id(self) + # normalize enums e.g. http.HTTPStatus + if isinstance(status_code, IntEnum): + status_code = int(status_code) + self.status_code = status_code + if self.response_model: + assert is_body_allowed_for_status_code(status_code), ( + f"Status code {status_code} must not have a response body" + ) + response_name = "Response_" + self.unique_id + self.response_field = create_model_field( + name=response_name, + type_=self.response_model, + mode="serialization", + ) + # Create a clone of the field, so that a Pydantic submodel is not returned + # as is just because it's an instance of a subclass of a more limited class + # e.g. UserInDB (containing hashed_password) could be a subclass of User + # that doesn't have the hashed_password. But because it's a subclass, it + # would pass the validation and be returned as is. + # By being a new field, no inheritance will be passed as is. A new model + # will always be created. + # TODO: remove when deprecating Pydantic v1 + self.secure_cloned_response_field: Optional[ModelField] = ( + create_cloned_field(self.response_field) + ) + else: + self.response_field = None # type: ignore + self.secure_cloned_response_field = None + self.dependencies = list(dependencies or []) + self.description = description or inspect.cleandoc(self.endpoint.__doc__ or "") + # if a "form feed" character (page break) is found in the description text, + # truncate description text to the content preceding the first "form feed" + self.description = self.description.split("\f")[0].strip() + response_fields = {} + for additional_status_code, response in self.responses.items(): + assert isinstance(response, dict), "An additional response must be a dict" + model = response.get("model") + if model: + assert is_body_allowed_for_status_code(additional_status_code), ( + f"Status code {additional_status_code} must not have a response body" + ) + response_name = f"Response_{additional_status_code}_{self.unique_id}" + response_field = create_model_field( + name=response_name, type_=model, mode="serialization" + ) + response_fields[additional_status_code] = response_field + if response_fields: + self.response_fields: Dict[Union[int, str], ModelField] = response_fields + else: + self.response_fields = {} + + assert callable(endpoint), "An endpoint must be a callable" + self.dependant = get_dependant(path=self.path_format, call=self.endpoint) + for depends in self.dependencies[::-1]: + self.dependant.dependencies.insert( + 0, + get_parameterless_sub_dependant(depends=depends, path=self.path_format), + ) + self._flat_dependant = get_flat_dependant(self.dependant) + self._embed_body_fields = _should_embed_body_fields( + self._flat_dependant.body_params + ) + self.body_field = get_body_field( + flat_dependant=self._flat_dependant, + name=self.unique_id, + embed_body_fields=self._embed_body_fields, + ) + self.app = request_response(self.get_route_handler()) + + def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]: + return get_request_handler( + dependant=self.dependant, + body_field=self.body_field, + status_code=self.status_code, + response_class=self.response_class, + response_field=self.secure_cloned_response_field, + response_model_include=self.response_model_include, + response_model_exclude=self.response_model_exclude, + response_model_by_alias=self.response_model_by_alias, + response_model_exclude_unset=self.response_model_exclude_unset, + response_model_exclude_defaults=self.response_model_exclude_defaults, + response_model_exclude_none=self.response_model_exclude_none, + dependency_overrides_provider=self.dependency_overrides_provider, + embed_body_fields=self._embed_body_fields, + ) + + def matches(self, scope: Scope) -> Tuple[Match, Scope]: + match, child_scope = super().matches(scope) + if match != Match.NONE: + child_scope["route"] = self + return match, child_scope + + +class APIRouter(routing.Router): + """ + `APIRouter` class, used to group *path operations*, for example to structure + an app in multiple files. It would then be included in the `FastAPI` app, or + in another `APIRouter` (ultimately included in the app). + + Read more about it in the + [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/). + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + + app = FastAPI() + router = APIRouter() + + + @router.get("/users/", tags=["users"]) + async def read_users(): + return [{"username": "Rick"}, {"username": "Morty"}] + + + app.include_router(router) + ``` + """ + + def __init__( + self, + *, + prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to all the *path operations* in this + router. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to all the + *path operations* in this router. + + Read more about it in the + [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + """ + ), + ] = None, + default_response_class: Annotated[ + Type[Response], + Doc( + """ + The default response class to be used. + + Read more in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). + """ + ), + ] = Default(JSONResponse), + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses to be shown in OpenAPI. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/). + + And in the + [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + OpenAPI callbacks that should apply to all *path operations* in this + router. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + routes: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + **Note**: you probably shouldn't use this parameter, it is inherited + from Starlette and supported for compatibility. + + --- + + A list of routes to serve incoming HTTP and WebSocket requests. + """ + ), + deprecated( + """ + You normally wouldn't use this parameter with FastAPI, it is inherited + from Starlette and supported for compatibility. + + In FastAPI, you normally would use the *path operation methods*, + like `router.get()`, `router.post()`, etc. + """ + ), + ] = None, + redirect_slashes: Annotated[ + bool, + Doc( + """ + Whether to detect and redirect slashes in URLs when the client doesn't + use the same format. + """ + ), + ] = True, + default: Annotated[ + Optional[ASGIApp], + Doc( + """ + Default function handler for this router. Used to handle + 404 Not Found errors. + """ + ), + ] = None, + dependency_overrides_provider: Annotated[ + Optional[Any], + Doc( + """ + Only used internally by FastAPI to handle dependency overrides. + + You shouldn't need to use it. It normally points to the `FastAPI` app + object. + """ + ), + ] = None, + route_class: Annotated[ + Type[APIRoute], + Doc( + """ + Custom route (*path operation*) class to be used by this router. + + Read more about it in the + [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router). + """ + ), + ] = APIRoute, + on_startup: Annotated[ + Optional[Sequence[Callable[[], Any]]], + Doc( + """ + A list of startup event handler functions. + + You should instead use the `lifespan` handlers. + + Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). + """ + ), + ] = None, + on_shutdown: Annotated[ + Optional[Sequence[Callable[[], Any]]], + Doc( + """ + A list of shutdown event handler functions. + + You should instead use the `lifespan` handlers. + + Read more in the + [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). + """ + ), + ] = None, + # the generic to Lifespan[AppType] is the type of the top level application + # which the router cannot know statically, so we use typing.Any + lifespan: Annotated[ + Optional[Lifespan[Any]], + Doc( + """ + A `Lifespan` context manager handler. This replaces `startup` and + `shutdown` functions with a single context manager. + + Read more in the + [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark all *path operations* in this router as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + To include (or not) all the *path operations* in this router in the + generated OpenAPI. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> None: + super().__init__( + routes=routes, + redirect_slashes=redirect_slashes, + default=default, + on_startup=on_startup, + on_shutdown=on_shutdown, + lifespan=lifespan, + ) + if prefix: + assert prefix.startswith("/"), "A path prefix must start with '/'" + assert not prefix.endswith("/"), ( + "A path prefix must not end with '/', as the routes will start with '/'" + ) + self.prefix = prefix + self.tags: List[Union[str, Enum]] = tags or [] + self.dependencies = list(dependencies or []) + self.deprecated = deprecated + self.include_in_schema = include_in_schema + self.responses = responses or {} + self.callbacks = callbacks or [] + self.dependency_overrides_provider = dependency_overrides_provider + self.route_class = route_class + self.default_response_class = default_response_class + self.generate_unique_id_function = generate_unique_id_function + + def route( + self, + path: str, + methods: Optional[List[str]] = None, + name: Optional[str] = None, + include_in_schema: bool = True, + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_route( + path, + func, + methods=methods, + name=name, + include_in_schema=include_in_schema, + ) + return func + + return decorator + + def add_api_route( + self, + path: str, + endpoint: Callable[..., Any], + *, + response_model: Any = Default(None), + status_code: Optional[int] = None, + tags: Optional[List[Union[str, Enum]]] = None, + dependencies: Optional[Sequence[params.Depends]] = None, + summary: Optional[str] = None, + description: Optional[str] = None, + response_description: str = "Successful Response", + responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, + deprecated: Optional[bool] = None, + methods: Optional[Union[Set[str], List[str]]] = None, + operation_id: Optional[str] = None, + response_model_include: Optional[IncEx] = None, + response_model_exclude: Optional[IncEx] = None, + response_model_by_alias: bool = True, + response_model_exclude_unset: bool = False, + response_model_exclude_defaults: bool = False, + response_model_exclude_none: bool = False, + include_in_schema: bool = True, + response_class: Union[Type[Response], DefaultPlaceholder] = Default( + JSONResponse + ), + name: Optional[str] = None, + route_class_override: Optional[Type[APIRoute]] = None, + callbacks: Optional[List[BaseRoute]] = None, + openapi_extra: Optional[Dict[str, Any]] = None, + generate_unique_id_function: Union[ + Callable[[APIRoute], str], DefaultPlaceholder + ] = Default(generate_unique_id), + ) -> None: + route_class = route_class_override or self.route_class + responses = responses or {} + combined_responses = {**self.responses, **responses} + current_response_class = get_value_or_default( + response_class, self.default_response_class + ) + current_tags = self.tags.copy() + if tags: + current_tags.extend(tags) + current_dependencies = self.dependencies.copy() + if dependencies: + current_dependencies.extend(dependencies) + current_callbacks = self.callbacks.copy() + if callbacks: + current_callbacks.extend(callbacks) + current_generate_unique_id = get_value_or_default( + generate_unique_id_function, self.generate_unique_id_function + ) + route = route_class( + self.prefix + path, + endpoint=endpoint, + response_model=response_model, + status_code=status_code, + tags=current_tags, + dependencies=current_dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=combined_responses, + deprecated=deprecated or self.deprecated, + methods=methods, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema and self.include_in_schema, + response_class=current_response_class, + name=name, + dependency_overrides_provider=self.dependency_overrides_provider, + callbacks=current_callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=current_generate_unique_id, + ) + self.routes.append(route) + + def api_route( + self, + path: str, + *, + response_model: Any = Default(None), + status_code: Optional[int] = None, + tags: Optional[List[Union[str, Enum]]] = None, + dependencies: Optional[Sequence[params.Depends]] = None, + summary: Optional[str] = None, + description: Optional[str] = None, + response_description: str = "Successful Response", + responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None, + deprecated: Optional[bool] = None, + methods: Optional[List[str]] = None, + operation_id: Optional[str] = None, + response_model_include: Optional[IncEx] = None, + response_model_exclude: Optional[IncEx] = None, + response_model_by_alias: bool = True, + response_model_exclude_unset: bool = False, + response_model_exclude_defaults: bool = False, + response_model_exclude_none: bool = False, + include_in_schema: bool = True, + response_class: Type[Response] = Default(JSONResponse), + name: Optional[str] = None, + callbacks: Optional[List[BaseRoute]] = None, + openapi_extra: Optional[Dict[str, Any]] = None, + generate_unique_id_function: Callable[[APIRoute], str] = Default( + generate_unique_id + ), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_api_route( + path, + func, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=methods, + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + return func + + return decorator + + def add_api_websocket_route( + self, + path: str, + endpoint: Callable[..., Any], + name: Optional[str] = None, + *, + dependencies: Optional[Sequence[params.Depends]] = None, + ) -> None: + current_dependencies = self.dependencies.copy() + if dependencies: + current_dependencies.extend(dependencies) + + route = APIWebSocketRoute( + self.prefix + path, + endpoint=endpoint, + name=name, + dependencies=current_dependencies, + dependency_overrides_provider=self.dependency_overrides_provider, + ) + self.routes.append(route) + + def websocket( + self, + path: Annotated[ + str, + Doc( + """ + WebSocket path. + """ + ), + ], + name: Annotated[ + Optional[str], + Doc( + """ + A name for the WebSocket. Only used internally. + """ + ), + ] = None, + *, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be used for this + WebSocket. + + Read more about it in the + [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). + """ + ), + ] = None, + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Decorate a WebSocket function. + + Read more about it in the + [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). + + **Example** + + ## Example + + ```python + from fastapi import APIRouter, FastAPI, WebSocket + + app = FastAPI() + router = APIRouter() + + @router.websocket("/ws") + async def websocket_endpoint(websocket: WebSocket): + await websocket.accept() + while True: + data = await websocket.receive_text() + await websocket.send_text(f"Message text was: {data}") + + app.include_router(router) + ``` + """ + + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_api_websocket_route( + path, func, name=name, dependencies=dependencies + ) + return func + + return decorator + + def websocket_route( + self, path: str, name: Union[str, None] = None + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_websocket_route(path, func, name=name) + return func + + return decorator + + def include_router( + self, + router: Annotated["APIRouter", Doc("The `APIRouter` to include.")], + *, + prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to all the *path operations* in this + router. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to all the + *path operations* in this router. + + Read more about it in the + [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + """ + ), + ] = None, + default_response_class: Annotated[ + Type[Response], + Doc( + """ + The default response class to be used. + + Read more in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). + """ + ), + ] = Default(JSONResponse), + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses to be shown in OpenAPI. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/). + + And in the + [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + OpenAPI callbacks that should apply to all *path operations* in this + router. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark all *path operations* in this router as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include (or not) all the *path operations* in this router in the + generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = True, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> None: + """ + Include another `APIRouter` in the same current `APIRouter`. + + Read more about it in the + [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/). + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + + app = FastAPI() + internal_router = APIRouter() + users_router = APIRouter() + + @users_router.get("/users/") + def read_users(): + return [{"name": "Rick"}, {"name": "Morty"}] + + internal_router.include_router(users_router) + app.include_router(internal_router) + ``` + """ + if prefix: + assert prefix.startswith("/"), "A path prefix must start with '/'" + assert not prefix.endswith("/"), ( + "A path prefix must not end with '/', as the routes will start with '/'" + ) + else: + for r in router.routes: + path = getattr(r, "path") # noqa: B009 + name = getattr(r, "name", "unknown") + if path is not None and not path: + raise FastAPIError( + f"Prefix and path cannot be both empty (path operation: {name})" + ) + if responses is None: + responses = {} + for route in router.routes: + if isinstance(route, APIRoute): + combined_responses = {**responses, **route.responses} + use_response_class = get_value_or_default( + route.response_class, + router.default_response_class, + default_response_class, + self.default_response_class, + ) + current_tags = [] + if tags: + current_tags.extend(tags) + if route.tags: + current_tags.extend(route.tags) + current_dependencies: List[params.Depends] = [] + if dependencies: + current_dependencies.extend(dependencies) + if route.dependencies: + current_dependencies.extend(route.dependencies) + current_callbacks = [] + if callbacks: + current_callbacks.extend(callbacks) + if route.callbacks: + current_callbacks.extend(route.callbacks) + current_generate_unique_id = get_value_or_default( + route.generate_unique_id_function, + router.generate_unique_id_function, + generate_unique_id_function, + self.generate_unique_id_function, + ) + self.add_api_route( + prefix + route.path, + route.endpoint, + response_model=route.response_model, + status_code=route.status_code, + tags=current_tags, + dependencies=current_dependencies, + summary=route.summary, + description=route.description, + response_description=route.response_description, + responses=combined_responses, + deprecated=route.deprecated or deprecated or self.deprecated, + methods=route.methods, + operation_id=route.operation_id, + response_model_include=route.response_model_include, + response_model_exclude=route.response_model_exclude, + response_model_by_alias=route.response_model_by_alias, + response_model_exclude_unset=route.response_model_exclude_unset, + response_model_exclude_defaults=route.response_model_exclude_defaults, + response_model_exclude_none=route.response_model_exclude_none, + include_in_schema=route.include_in_schema + and self.include_in_schema + and include_in_schema, + response_class=use_response_class, + name=route.name, + route_class_override=type(route), + callbacks=current_callbacks, + openapi_extra=route.openapi_extra, + generate_unique_id_function=current_generate_unique_id, + ) + elif isinstance(route, routing.Route): + methods = list(route.methods or []) + self.add_route( + prefix + route.path, + route.endpoint, + methods=methods, + include_in_schema=route.include_in_schema, + name=route.name, + ) + elif isinstance(route, APIWebSocketRoute): + current_dependencies = [] + if dependencies: + current_dependencies.extend(dependencies) + if route.dependencies: + current_dependencies.extend(route.dependencies) + self.add_api_websocket_route( + prefix + route.path, + route.endpoint, + dependencies=current_dependencies, + name=route.name, + ) + elif isinstance(route, routing.WebSocketRoute): + self.add_websocket_route( + prefix + route.path, route.endpoint, name=route.name + ) + for handler in router.on_startup: + self.add_event_handler("startup", handler) + for handler in router.on_shutdown: + self.add_event_handler("shutdown", handler) + self.lifespan_context = _merge_lifespan_context( + self.lifespan_context, + router.lifespan_context, + ) + + def get( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP GET operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + + app = FastAPI() + router = APIRouter() + + @router.get("/items/") + def read_items(): + return [{"name": "Empanada"}, {"name": "Arepa"}] + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["GET"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def put( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP PUT operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + router = APIRouter() + + @router.put("/items/{item_id}") + def replace_item(item_id: str, item: Item): + return {"message": "Item replaced", "id": item_id} + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["PUT"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def post( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP POST operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + router = APIRouter() + + @router.post("/items/") + def create_item(item: Item): + return {"message": "Item created"} + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["POST"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def delete( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP DELETE operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + + app = FastAPI() + router = APIRouter() + + @router.delete("/items/{item_id}") + def delete_item(item_id: str): + return {"message": "Item deleted"} + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["DELETE"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def options( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP OPTIONS operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + + app = FastAPI() + router = APIRouter() + + @router.options("/items/") + def get_item_options(): + return {"additions": ["Aji", "Guacamole"]} + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["OPTIONS"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def head( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP HEAD operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + router = APIRouter() + + @router.head("/items/", status_code=204) + def get_items_headers(response: Response): + response.headers["X-Cat-Dog"] = "Alone in the world" + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["HEAD"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def patch( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP PATCH operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + router = APIRouter() + + @router.patch("/items/") + def update_item(item: Item): + return {"message": "Item updated in place"} + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["PATCH"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + def trace( + self, + path: Annotated[ + str, + Doc( + """ + The URL path to be used for this *path operation*. + + For example, in `http://example.com/items`, the path is `/items`. + """ + ), + ], + *, + response_model: Annotated[ + Any, + Doc( + """ + The type to use for the response. + + It could be any valid Pydantic *field* type. So, it doesn't have to + be a Pydantic model, it could be other things, like a `list`, `dict`, + etc. + + It will be used for: + + * Documentation: the generated OpenAPI (and the UI at `/docs`) will + show it as the response (JSON Schema). + * Serialization: you could return an arbitrary object and the + `response_model` would be used to serialize that object into the + corresponding JSON. + * Filtering: the JSON sent to the client will only contain the data + (fields) defined in the `response_model`. If you returned an object + that contains an attribute `password` but the `response_model` does + not include that field, the JSON sent to the client would not have + that `password`. + * Validation: whatever you return will be serialized with the + `response_model`, converting any data as necessary to generate the + corresponding JSON. But if the data in the object returned is not + valid, that would mean a violation of the contract with the client, + so it's an error from the API developer. So, FastAPI will raise an + error and return a 500 error code (Internal Server Error). + + Read more about it in the + [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). + """ + ), + ] = Default(None), + status_code: Annotated[ + Optional[int], + Doc( + """ + The default status code to be used for the response. + + You could override the status code by returning a response directly. + + Read more about it in the + [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). + """ + ), + ] = None, + tags: Annotated[ + Optional[List[Union[str, Enum]]], + Doc( + """ + A list of tags to be applied to the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). + """ + ), + ] = None, + dependencies: Annotated[ + Optional[Sequence[params.Depends]], + Doc( + """ + A list of dependencies (using `Depends()`) to be applied to the + *path operation*. + + Read more about it in the + [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). + """ + ), + ] = None, + summary: Annotated[ + Optional[str], + Doc( + """ + A summary for the *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + A description for the *path operation*. + + If not provided, it will be extracted automatically from the docstring + of the *path operation function*. + + It can contain Markdown. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + """ + ), + ] = None, + response_description: Annotated[ + str, + Doc( + """ + The description for the default response. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = "Successful Response", + responses: Annotated[ + Optional[Dict[Union[int, str], Dict[str, Any]]], + Doc( + """ + Additional responses that could be returned by this *path operation*. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + deprecated: Annotated[ + Optional[bool], + Doc( + """ + Mark this *path operation* as deprecated. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + operation_id: Annotated[ + Optional[str], + Doc( + """ + Custom operation ID to be used by this *path operation*. + + By default, it is generated automatically. + + If you provide a custom operation ID, you need to make sure it is + unique for the whole API. + + You can customize the + operation ID generation with the parameter + `generate_unique_id_function` in the `FastAPI` class. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = None, + response_model_include: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to include only certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_exclude: Annotated[ + Optional[IncEx], + Doc( + """ + Configuration passed to Pydantic to exclude certain fields in the + response data. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = None, + response_model_by_alias: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response model + should be serialized by alias when an alias is used. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). + """ + ), + ] = True, + response_model_exclude_unset: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that were not set and + have their default values. This is different from + `response_model_exclude_defaults` in that if the fields are set, + they will be included in the response, even if the value is the same + as the default. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_defaults: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data + should have all the fields, including the ones that have the same value + as the default. This is different from `response_model_exclude_unset` + in that if the fields are set but contain the same default values, + they will be excluded from the response. + + When `True`, default values are omitted from the response. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). + """ + ), + ] = False, + response_model_exclude_none: Annotated[ + bool, + Doc( + """ + Configuration passed to Pydantic to define if the response data should + exclude fields set to `None`. + + This is much simpler (less smart) than `response_model_exclude_unset` + and `response_model_exclude_defaults`. You probably want to use one of + those two instead of this one, as those allow returning `None` values + when it makes sense. + + Read more about it in the + [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). + """ + ), + ] = False, + include_in_schema: Annotated[ + bool, + Doc( + """ + Include this *path operation* in the generated OpenAPI schema. + + This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). + """ + ), + ] = True, + response_class: Annotated[ + Type[Response], + Doc( + """ + Response class to be used for this *path operation*. + + This will not be used if you return a response directly. + + Read more about it in the + [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). + """ + ), + ] = Default(JSONResponse), + name: Annotated[ + Optional[str], + Doc( + """ + Name for this *path operation*. Only used internally. + """ + ), + ] = None, + callbacks: Annotated[ + Optional[List[BaseRoute]], + Doc( + """ + List of *path operations* that will be used as OpenAPI callbacks. + + This is only for OpenAPI documentation, the callbacks won't be used + directly. + + It will be added to the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). + """ + ), + ] = None, + openapi_extra: Annotated[ + Optional[Dict[str, Any]], + Doc( + """ + Extra metadata to be included in the OpenAPI schema for this *path + operation*. + + Read more about it in the + [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). + """ + ), + ] = None, + generate_unique_id_function: Annotated[ + Callable[[APIRoute], str], + Doc( + """ + Customize the function used to generate unique IDs for the *path + operations* shown in the generated OpenAPI. + + This is particularly useful when automatically generating clients or + SDKs for your API. + + Read more about it in the + [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). + """ + ), + ] = Default(generate_unique_id), + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add a *path operation* using an HTTP TRACE operation. + + ## Example + + ```python + from fastapi import APIRouter, FastAPI + from pydantic import BaseModel + + class Item(BaseModel): + name: str + description: str | None = None + + app = FastAPI() + router = APIRouter() + + @router.trace("/items/{item_id}") + def trace_item(item_id: str): + return None + + app.include_router(router) + ``` + """ + return self.api_route( + path=path, + response_model=response_model, + status_code=status_code, + tags=tags, + dependencies=dependencies, + summary=summary, + description=description, + response_description=response_description, + responses=responses, + deprecated=deprecated, + methods=["TRACE"], + operation_id=operation_id, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, + include_in_schema=include_in_schema, + response_class=response_class, + name=name, + callbacks=callbacks, + openapi_extra=openapi_extra, + generate_unique_id_function=generate_unique_id_function, + ) + + @deprecated( + """ + on_event is deprecated, use lifespan event handlers instead. + + Read more about it in the + [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/). + """ + ) + def on_event( + self, + event_type: Annotated[ + str, + Doc( + """ + The type of event. `startup` or `shutdown`. + """ + ), + ], + ) -> Callable[[DecoratedCallable], DecoratedCallable]: + """ + Add an event handler for the router. + + `on_event` is deprecated, use `lifespan` event handlers instead. + + Read more about it in the + [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated). + """ + + def decorator(func: DecoratedCallable) -> DecoratedCallable: + self.add_event_handler(event_type, func) + return func + + return decorator diff --git a/venv/lib/python3.11/site-packages/fastapi/security/__init__.py b/venv/lib/python3.11/site-packages/fastapi/security/__init__.py new file mode 100644 index 0000000..3aa6bf2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/__init__.py @@ -0,0 +1,15 @@ +from .api_key import APIKeyCookie as APIKeyCookie +from .api_key import APIKeyHeader as APIKeyHeader +from .api_key import APIKeyQuery as APIKeyQuery +from .http import HTTPAuthorizationCredentials as HTTPAuthorizationCredentials +from .http import HTTPBasic as HTTPBasic +from .http import HTTPBasicCredentials as HTTPBasicCredentials +from .http import HTTPBearer as HTTPBearer +from .http import HTTPDigest as HTTPDigest +from .oauth2 import OAuth2 as OAuth2 +from .oauth2 import OAuth2AuthorizationCodeBearer as OAuth2AuthorizationCodeBearer +from .oauth2 import OAuth2PasswordBearer as OAuth2PasswordBearer +from .oauth2 import OAuth2PasswordRequestForm as OAuth2PasswordRequestForm +from .oauth2 import OAuth2PasswordRequestFormStrict as OAuth2PasswordRequestFormStrict +from .oauth2 import SecurityScopes as SecurityScopes +from .open_id_connect_url import OpenIdConnect as OpenIdConnect diff --git a/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cb3c9fddcc7003cbad99f2cb94a5185623a5e2a GIT binary patch literal 1072 zcmZ{i-D=c86vrp~k^Rhmv;|pEyz#;nY*_VDs_lxj3hml0y_gF_OvZNHB$G~(UE+)Q z2;wXF6muE&RuIG+p?AIV%xqg3ScgARmdjIqH*+m(lA2PUErE9qS z4)6u}$TtEM8rU!-mw-#Sq__-R#%0Bopb}PbRdE&A#HL~sxQ1(rYru6}S6l~f;D+Kx z&nN_fJkHyIFe9IQ{IVltp7sd=jP94HBp~WPQ&~ zs0YE;ZJtC=ov{;c*i`FyFUTCw<5h6^U2=Li(9J)CT@}}824}U13iCC zE;88rHRB=ddjG%0Y09Z5KcO=vUdCyfPdyeBIhA!3ljy)7vnV27dN|x%*4&snGm>+- zAc$9_Rl$~(^E8dQDdU>7y0nHgd8d{pbLDirB{OYlmb8wvuCyN5aueD{4)q;x)zHa! z!23}7hAzR;)u}yqxxH8{Y!b3hl+0O>$+NKMB%0d+{b0vA98vUido;2Wnv%z{>&;yF z#r8)xN#Wb=f}(o~>B zp{qa-g{}ha2weqwBy_FIJP=4zfsTc)0=*Qv3iL+kD$uFWRiI}=SAkxLb>es67ySiJ C%{?Cg literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/api_key.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/api_key.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30b3f48ed98504097e1139b47266a355d3c2adb9 GIT binary patch literal 10304 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 G)qerw^E+Pv literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/base.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c2105279786c6bb2131d2c1b1fdfcbb5e0a94db GIT binary patch literal 594 zcmZuuJxc>Y5S_idNKm5$)GDP-M6-ykSco7NrZCu~a9MMsp5B+Ymka4EY_0PT6!Fg_ zUAR^d#3m9eD`z(m6rG!W`)2RW&duCIsWb~@Coga3ceFq2;M<%j8Lt!RfeSA4Az)35 zfd%{ETDRcZ_ZGktt%)_6>olNRc-3K*YH}VW<%KtPmt=`$&9Vi0iiW zwTPnf&#yT&*DMMl!!Sx^>P4XPX59Bq zdE8AeqHwFWxyhB6;zlf6SMnScKa(nzvB#-v(?36@0o3BI>A`@Wu396w`SA?rDt$-$ zz^M$&OMOTCz#x%if#fE+UbXX;X^mPGV@S1XW-w|}LI2gHq`~AY68kJ}Pv)|dlqqDi f)B(ZBW{eGCum9UeGZtGO!C!dSXCME(Fr~f#QWlu} literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/http.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/http.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4b5e77c0c6b432ee562543af7398f5ea29ed51f GIT binary patch literal 15008 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 E0BJgWBme*a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/oauth2.cpython-311.pyc b/venv/lib/python3.11/site-packages/fastapi/security/__pycache__/oauth2.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ab9e4e0ed3cbcc5aec7d665ede6af0e94bb6294 GIT binary patch literal 20304 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/fastapi/security/api_key.py b/venv/lib/python3.11/site-packages/fastapi/security/api_key.py new file mode 100644 index 0000000..70c2dca --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/api_key.py @@ -0,0 +1,288 @@ +from typing import Optional + +from fastapi.openapi.models import APIKey, APIKeyIn +from fastapi.security.base import SecurityBase +from starlette.exceptions import HTTPException +from starlette.requests import Request +from starlette.status import HTTP_403_FORBIDDEN +from typing_extensions import Annotated, Doc + + +class APIKeyBase(SecurityBase): + @staticmethod + def check_api_key(api_key: Optional[str], auto_error: bool) -> Optional[str]: + if not api_key: + if auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" + ) + return None + return api_key + + +class APIKeyQuery(APIKeyBase): + """ + API key authentication using a query parameter. + + This defines the name of the query parameter that should be provided in the request + with the API key and integrates that into the OpenAPI documentation. It extracts + the key value sent in the query parameter automatically and provides it as the + dependency result. But it doesn't define how to send that API key to the client. + + ## Usage + + Create an instance object and use that object as the dependency in `Depends()`. + + The dependency result will be a string containing the key value. + + ## Example + + ```python + from fastapi import Depends, FastAPI + from fastapi.security import APIKeyQuery + + app = FastAPI() + + query_scheme = APIKeyQuery(name="api_key") + + + @app.get("/items/") + async def read_items(api_key: str = Depends(query_scheme)): + return {"api_key": api_key} + ``` + """ + + def __init__( + self, + *, + name: Annotated[ + str, + Doc("Query parameter name."), + ], + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if the query parameter is not provided, `APIKeyQuery` will + automatically cancel the request and send the client an error. + + If `auto_error` is set to `False`, when the query parameter is not + available, instead of erroring out, the dependency result will be + `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, in a query + parameter or in an HTTP Bearer token). + """ + ), + ] = True, + ): + self.model: APIKey = APIKey( + **{"in": APIKeyIn.query}, # type: ignore[arg-type] + name=name, + description=description, + ) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__(self, request: Request) -> Optional[str]: + api_key = request.query_params.get(self.model.name) + return self.check_api_key(api_key, self.auto_error) + + +class APIKeyHeader(APIKeyBase): + """ + API key authentication using a header. + + This defines the name of the header that should be provided in the request with + the API key and integrates that into the OpenAPI documentation. It extracts + the key value sent in the header automatically and provides it as the dependency + result. But it doesn't define how to send that key to the client. + + ## Usage + + Create an instance object and use that object as the dependency in `Depends()`. + + The dependency result will be a string containing the key value. + + ## Example + + ```python + from fastapi import Depends, FastAPI + from fastapi.security import APIKeyHeader + + app = FastAPI() + + header_scheme = APIKeyHeader(name="x-key") + + + @app.get("/items/") + async def read_items(key: str = Depends(header_scheme)): + return {"key": key} + ``` + """ + + def __init__( + self, + *, + name: Annotated[str, Doc("Header name.")], + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if the header is not provided, `APIKeyHeader` will + automatically cancel the request and send the client an error. + + If `auto_error` is set to `False`, when the header is not available, + instead of erroring out, the dependency result will be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, in a header or + in an HTTP Bearer token). + """ + ), + ] = True, + ): + self.model: APIKey = APIKey( + **{"in": APIKeyIn.header}, # type: ignore[arg-type] + name=name, + description=description, + ) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__(self, request: Request) -> Optional[str]: + api_key = request.headers.get(self.model.name) + return self.check_api_key(api_key, self.auto_error) + + +class APIKeyCookie(APIKeyBase): + """ + API key authentication using a cookie. + + This defines the name of the cookie that should be provided in the request with + the API key and integrates that into the OpenAPI documentation. It extracts + the key value sent in the cookie automatically and provides it as the dependency + result. But it doesn't define how to set that cookie. + + ## Usage + + Create an instance object and use that object as the dependency in `Depends()`. + + The dependency result will be a string containing the key value. + + ## Example + + ```python + from fastapi import Depends, FastAPI + from fastapi.security import APIKeyCookie + + app = FastAPI() + + cookie_scheme = APIKeyCookie(name="session") + + + @app.get("/items/") + async def read_items(session: str = Depends(cookie_scheme)): + return {"session": session} + ``` + """ + + def __init__( + self, + *, + name: Annotated[str, Doc("Cookie name.")], + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if the cookie is not provided, `APIKeyCookie` will + automatically cancel the request and send the client an error. + + If `auto_error` is set to `False`, when the cookie is not available, + instead of erroring out, the dependency result will be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, in a cookie or + in an HTTP Bearer token). + """ + ), + ] = True, + ): + self.model: APIKey = APIKey( + **{"in": APIKeyIn.cookie}, # type: ignore[arg-type] + name=name, + description=description, + ) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__(self, request: Request) -> Optional[str]: + api_key = request.cookies.get(self.model.name) + return self.check_api_key(api_key, self.auto_error) diff --git a/venv/lib/python3.11/site-packages/fastapi/security/base.py b/venv/lib/python3.11/site-packages/fastapi/security/base.py new file mode 100644 index 0000000..c43555d --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/base.py @@ -0,0 +1,6 @@ +from fastapi.openapi.models import SecurityBase as SecurityBaseModel + + +class SecurityBase: + model: SecurityBaseModel + scheme_name: str diff --git a/venv/lib/python3.11/site-packages/fastapi/security/http.py b/venv/lib/python3.11/site-packages/fastapi/security/http.py new file mode 100644 index 0000000..9ab2df3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/http.py @@ -0,0 +1,423 @@ +import binascii +from base64 import b64decode +from typing import Optional + +from fastapi.exceptions import HTTPException +from fastapi.openapi.models import HTTPBase as HTTPBaseModel +from fastapi.openapi.models import HTTPBearer as HTTPBearerModel +from fastapi.security.base import SecurityBase +from fastapi.security.utils import get_authorization_scheme_param +from pydantic import BaseModel +from starlette.requests import Request +from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN +from typing_extensions import Annotated, Doc + + +class HTTPBasicCredentials(BaseModel): + """ + The HTTP Basic credentials given as the result of using `HTTPBasic` in a + dependency. + + Read more about it in the + [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/). + """ + + username: Annotated[str, Doc("The HTTP Basic username.")] + password: Annotated[str, Doc("The HTTP Basic password.")] + + +class HTTPAuthorizationCredentials(BaseModel): + """ + The HTTP authorization credentials in the result of using `HTTPBearer` or + `HTTPDigest` in a dependency. + + The HTTP authorization header value is split by the first space. + + The first part is the `scheme`, the second part is the `credentials`. + + For example, in an HTTP Bearer token scheme, the client will send a header + like: + + ``` + Authorization: Bearer deadbeef12346 + ``` + + In this case: + + * `scheme` will have the value `"Bearer"` + * `credentials` will have the value `"deadbeef12346"` + """ + + scheme: Annotated[ + str, + Doc( + """ + The HTTP authorization scheme extracted from the header value. + """ + ), + ] + credentials: Annotated[ + str, + Doc( + """ + The HTTP authorization credentials extracted from the header value. + """ + ), + ] + + +class HTTPBase(SecurityBase): + def __init__( + self, + *, + scheme: str, + scheme_name: Optional[str] = None, + description: Optional[str] = None, + auto_error: bool = True, + ): + self.model = HTTPBaseModel(scheme=scheme, description=description) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__( + self, request: Request + ) -> Optional[HTTPAuthorizationCredentials]: + authorization = request.headers.get("Authorization") + scheme, credentials = get_authorization_scheme_param(authorization) + if not (authorization and scheme and credentials): + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" + ) + else: + return None + return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) + + +class HTTPBasic(HTTPBase): + """ + HTTP Basic authentication. + + ## Usage + + Create an instance object and use that object as the dependency in `Depends()`. + + The dependency result will be an `HTTPBasicCredentials` object containing the + `username` and the `password`. + + Read more about it in the + [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/). + + ## Example + + ```python + from typing import Annotated + + from fastapi import Depends, FastAPI + from fastapi.security import HTTPBasic, HTTPBasicCredentials + + app = FastAPI() + + security = HTTPBasic() + + + @app.get("/users/me") + def read_current_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]): + return {"username": credentials.username, "password": credentials.password} + ``` + """ + + def __init__( + self, + *, + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + realm: Annotated[ + Optional[str], + Doc( + """ + HTTP Basic authentication realm. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if the HTTP Basic authentication is not provided (a + header), `HTTPBasic` will automatically cancel the request and send the + client an error. + + If `auto_error` is set to `False`, when the HTTP Basic authentication + is not available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, in HTTP Basic + authentication or in an HTTP Bearer token). + """ + ), + ] = True, + ): + self.model = HTTPBaseModel(scheme="basic", description=description) + self.scheme_name = scheme_name or self.__class__.__name__ + self.realm = realm + self.auto_error = auto_error + + async def __call__( # type: ignore + self, request: Request + ) -> Optional[HTTPBasicCredentials]: + authorization = request.headers.get("Authorization") + scheme, param = get_authorization_scheme_param(authorization) + if self.realm: + unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'} + else: + unauthorized_headers = {"WWW-Authenticate": "Basic"} + if not authorization or scheme.lower() != "basic": + if self.auto_error: + raise HTTPException( + status_code=HTTP_401_UNAUTHORIZED, + detail="Not authenticated", + headers=unauthorized_headers, + ) + else: + return None + invalid_user_credentials_exc = HTTPException( + status_code=HTTP_401_UNAUTHORIZED, + detail="Invalid authentication credentials", + headers=unauthorized_headers, + ) + try: + data = b64decode(param).decode("ascii") + except (ValueError, UnicodeDecodeError, binascii.Error): + raise invalid_user_credentials_exc # noqa: B904 + username, separator, password = data.partition(":") + if not separator: + raise invalid_user_credentials_exc + return HTTPBasicCredentials(username=username, password=password) + + +class HTTPBearer(HTTPBase): + """ + HTTP Bearer token authentication. + + ## Usage + + Create an instance object and use that object as the dependency in `Depends()`. + + The dependency result will be an `HTTPAuthorizationCredentials` object containing + the `scheme` and the `credentials`. + + ## Example + + ```python + from typing import Annotated + + from fastapi import Depends, FastAPI + from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer + + app = FastAPI() + + security = HTTPBearer() + + + @app.get("/users/me") + def read_current_user( + credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)] + ): + return {"scheme": credentials.scheme, "credentials": credentials.credentials} + ``` + """ + + def __init__( + self, + *, + bearerFormat: Annotated[Optional[str], Doc("Bearer token format.")] = None, + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if the HTTP Bearer token is not provided (in an + `Authorization` header), `HTTPBearer` will automatically cancel the + request and send the client an error. + + If `auto_error` is set to `False`, when the HTTP Bearer token + is not available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, in an HTTP + Bearer token or in a cookie). + """ + ), + ] = True, + ): + self.model = HTTPBearerModel(bearerFormat=bearerFormat, description=description) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__( + self, request: Request + ) -> Optional[HTTPAuthorizationCredentials]: + authorization = request.headers.get("Authorization") + scheme, credentials = get_authorization_scheme_param(authorization) + if not (authorization and scheme and credentials): + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" + ) + else: + return None + if scheme.lower() != "bearer": + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, + detail="Invalid authentication credentials", + ) + else: + return None + return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) + + +class HTTPDigest(HTTPBase): + """ + HTTP Digest authentication. + + ## Usage + + Create an instance object and use that object as the dependency in `Depends()`. + + The dependency result will be an `HTTPAuthorizationCredentials` object containing + the `scheme` and the `credentials`. + + ## Example + + ```python + from typing import Annotated + + from fastapi import Depends, FastAPI + from fastapi.security import HTTPAuthorizationCredentials, HTTPDigest + + app = FastAPI() + + security = HTTPDigest() + + + @app.get("/users/me") + def read_current_user( + credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)] + ): + return {"scheme": credentials.scheme, "credentials": credentials.credentials} + ``` + """ + + def __init__( + self, + *, + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if the HTTP Digest is not provided, `HTTPDigest` will + automatically cancel the request and send the client an error. + + If `auto_error` is set to `False`, when the HTTP Digest is not + available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, in HTTP + Digest or in a cookie). + """ + ), + ] = True, + ): + self.model = HTTPBaseModel(scheme="digest", description=description) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__( + self, request: Request + ) -> Optional[HTTPAuthorizationCredentials]: + authorization = request.headers.get("Authorization") + scheme, credentials = get_authorization_scheme_param(authorization) + if not (authorization and scheme and credentials): + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" + ) + else: + return None + if scheme.lower() != "digest": + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, + detail="Invalid authentication credentials", + ) + else: + return None + return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) diff --git a/venv/lib/python3.11/site-packages/fastapi/security/oauth2.py b/venv/lib/python3.11/site-packages/fastapi/security/oauth2.py new file mode 100644 index 0000000..5ffad59 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/oauth2.py @@ -0,0 +1,638 @@ +from typing import Any, Dict, List, Optional, Union, cast + +from fastapi.exceptions import HTTPException +from fastapi.openapi.models import OAuth2 as OAuth2Model +from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel +from fastapi.param_functions import Form +from fastapi.security.base import SecurityBase +from fastapi.security.utils import get_authorization_scheme_param +from starlette.requests import Request +from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN + +# TODO: import from typing when deprecating Python 3.9 +from typing_extensions import Annotated, Doc + + +class OAuth2PasswordRequestForm: + """ + This is a dependency class to collect the `username` and `password` as form data + for an OAuth2 password flow. + + The OAuth2 specification dictates that for a password flow the data should be + collected using form data (instead of JSON) and that it should have the specific + fields `username` and `password`. + + All the initialization parameters are extracted from the request. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). + + ## Example + + ```python + from typing import Annotated + + from fastapi import Depends, FastAPI + from fastapi.security import OAuth2PasswordRequestForm + + app = FastAPI() + + + @app.post("/login") + def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]): + data = {} + data["scopes"] = [] + for scope in form_data.scopes: + data["scopes"].append(scope) + if form_data.client_id: + data["client_id"] = form_data.client_id + if form_data.client_secret: + data["client_secret"] = form_data.client_secret + return data + ``` + + Note that for OAuth2 the scope `items:read` is a single scope in an opaque string. + You could have custom internal logic to separate it by colon characters (`:`) or + similar, and get the two parts `items` and `read`. Many applications do that to + group and organize permissions, you could do it as well in your application, just + know that that it is application specific, it's not part of the specification. + """ + + def __init__( + self, + *, + grant_type: Annotated[ + Union[str, None], + Form(pattern="^password$"), + Doc( + """ + The OAuth2 spec says it is required and MUST be the fixed string + "password". Nevertheless, this dependency class is permissive and + allows not passing it. If you want to enforce it, use instead the + `OAuth2PasswordRequestFormStrict` dependency. + """ + ), + ] = None, + username: Annotated[ + str, + Form(), + Doc( + """ + `username` string. The OAuth2 spec requires the exact field name + `username`. + """ + ), + ], + password: Annotated[ + str, + Form(), + Doc( + """ + `password` string. The OAuth2 spec requires the exact field name + `password". + """ + ), + ], + scope: Annotated[ + str, + Form(), + Doc( + """ + A single string with actually several scopes separated by spaces. Each + scope is also a string. + + For example, a single string with: + + ```python + "items:read items:write users:read profile openid" + ```` + + would represent the scopes: + + * `items:read` + * `items:write` + * `users:read` + * `profile` + * `openid` + """ + ), + ] = "", + client_id: Annotated[ + Union[str, None], + Form(), + Doc( + """ + If there's a `client_id`, it can be sent as part of the form fields. + But the OAuth2 specification recommends sending the `client_id` and + `client_secret` (if any) using HTTP Basic auth. + """ + ), + ] = None, + client_secret: Annotated[ + Union[str, None], + Form(), + Doc( + """ + If there's a `client_password` (and a `client_id`), they can be sent + as part of the form fields. But the OAuth2 specification recommends + sending the `client_id` and `client_secret` (if any) using HTTP Basic + auth. + """ + ), + ] = None, + ): + self.grant_type = grant_type + self.username = username + self.password = password + self.scopes = scope.split() + self.client_id = client_id + self.client_secret = client_secret + + +class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): + """ + This is a dependency class to collect the `username` and `password` as form data + for an OAuth2 password flow. + + The OAuth2 specification dictates that for a password flow the data should be + collected using form data (instead of JSON) and that it should have the specific + fields `username` and `password`. + + All the initialization parameters are extracted from the request. + + The only difference between `OAuth2PasswordRequestFormStrict` and + `OAuth2PasswordRequestForm` is that `OAuth2PasswordRequestFormStrict` requires the + client to send the form field `grant_type` with the value `"password"`, which + is required in the OAuth2 specification (it seems that for no particular reason), + while for `OAuth2PasswordRequestForm` `grant_type` is optional. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). + + ## Example + + ```python + from typing import Annotated + + from fastapi import Depends, FastAPI + from fastapi.security import OAuth2PasswordRequestForm + + app = FastAPI() + + + @app.post("/login") + def login(form_data: Annotated[OAuth2PasswordRequestFormStrict, Depends()]): + data = {} + data["scopes"] = [] + for scope in form_data.scopes: + data["scopes"].append(scope) + if form_data.client_id: + data["client_id"] = form_data.client_id + if form_data.client_secret: + data["client_secret"] = form_data.client_secret + return data + ``` + + Note that for OAuth2 the scope `items:read` is a single scope in an opaque string. + You could have custom internal logic to separate it by colon characters (`:`) or + similar, and get the two parts `items` and `read`. Many applications do that to + group and organize permissions, you could do it as well in your application, just + know that that it is application specific, it's not part of the specification. + + + grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password". + This dependency is strict about it. If you want to be permissive, use instead the + OAuth2PasswordRequestForm dependency class. + username: username string. The OAuth2 spec requires the exact field name "username". + password: password string. The OAuth2 spec requires the exact field name "password". + scope: Optional string. Several scopes (each one a string) separated by spaces. E.g. + "items:read items:write users:read profile openid" + client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any) + using HTTP Basic auth, as: client_id:client_secret + client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any) + using HTTP Basic auth, as: client_id:client_secret + """ + + def __init__( + self, + grant_type: Annotated[ + str, + Form(pattern="^password$"), + Doc( + """ + The OAuth2 spec says it is required and MUST be the fixed string + "password". This dependency is strict about it. If you want to be + permissive, use instead the `OAuth2PasswordRequestForm` dependency + class. + """ + ), + ], + username: Annotated[ + str, + Form(), + Doc( + """ + `username` string. The OAuth2 spec requires the exact field name + `username`. + """ + ), + ], + password: Annotated[ + str, + Form(), + Doc( + """ + `password` string. The OAuth2 spec requires the exact field name + `password". + """ + ), + ], + scope: Annotated[ + str, + Form(), + Doc( + """ + A single string with actually several scopes separated by spaces. Each + scope is also a string. + + For example, a single string with: + + ```python + "items:read items:write users:read profile openid" + ```` + + would represent the scopes: + + * `items:read` + * `items:write` + * `users:read` + * `profile` + * `openid` + """ + ), + ] = "", + client_id: Annotated[ + Union[str, None], + Form(), + Doc( + """ + If there's a `client_id`, it can be sent as part of the form fields. + But the OAuth2 specification recommends sending the `client_id` and + `client_secret` (if any) using HTTP Basic auth. + """ + ), + ] = None, + client_secret: Annotated[ + Union[str, None], + Form(), + Doc( + """ + If there's a `client_password` (and a `client_id`), they can be sent + as part of the form fields. But the OAuth2 specification recommends + sending the `client_id` and `client_secret` (if any) using HTTP Basic + auth. + """ + ), + ] = None, + ): + super().__init__( + grant_type=grant_type, + username=username, + password=password, + scope=scope, + client_id=client_id, + client_secret=client_secret, + ) + + +class OAuth2(SecurityBase): + """ + This is the base class for OAuth2 authentication, an instance of it would be used + as a dependency. All other OAuth2 classes inherit from it and customize it for + each OAuth2 flow. + + You normally would not create a new class inheriting from it but use one of the + existing subclasses, and maybe compose them if you want to support multiple flows. + + Read more about it in the + [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/). + """ + + def __init__( + self, + *, + flows: Annotated[ + Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]], + Doc( + """ + The dictionary of OAuth2 flows. + """ + ), + ] = OAuthFlowsModel(), + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if no HTTP Authorization header is provided, required for + OAuth2 authentication, it will automatically cancel the request and + send the client an error. + + If `auto_error` is set to `False`, when the HTTP Authorization header + is not available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, with OAuth2 + or in a cookie). + """ + ), + ] = True, + ): + self.model = OAuth2Model( + flows=cast(OAuthFlowsModel, flows), description=description + ) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__(self, request: Request) -> Optional[str]: + authorization = request.headers.get("Authorization") + if not authorization: + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" + ) + else: + return None + return authorization + + +class OAuth2PasswordBearer(OAuth2): + """ + OAuth2 flow for authentication using a bearer token obtained with a password. + An instance of it would be used as a dependency. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). + """ + + def __init__( + self, + tokenUrl: Annotated[ + str, + Doc( + """ + The URL to obtain the OAuth2 token. This would be the *path operation* + that has `OAuth2PasswordRequestForm` as a dependency. + """ + ), + ], + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + scopes: Annotated[ + Optional[Dict[str, str]], + Doc( + """ + The OAuth2 scopes that would be required by the *path operations* that + use this dependency. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if no HTTP Authorization header is provided, required for + OAuth2 authentication, it will automatically cancel the request and + send the client an error. + + If `auto_error` is set to `False`, when the HTTP Authorization header + is not available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, with OAuth2 + or in a cookie). + """ + ), + ] = True, + ): + if not scopes: + scopes = {} + flows = OAuthFlowsModel( + password=cast(Any, {"tokenUrl": tokenUrl, "scopes": scopes}) + ) + super().__init__( + flows=flows, + scheme_name=scheme_name, + description=description, + auto_error=auto_error, + ) + + async def __call__(self, request: Request) -> Optional[str]: + authorization = request.headers.get("Authorization") + scheme, param = get_authorization_scheme_param(authorization) + if not authorization or scheme.lower() != "bearer": + if self.auto_error: + raise HTTPException( + status_code=HTTP_401_UNAUTHORIZED, + detail="Not authenticated", + headers={"WWW-Authenticate": "Bearer"}, + ) + else: + return None + return param + + +class OAuth2AuthorizationCodeBearer(OAuth2): + """ + OAuth2 flow for authentication using a bearer token obtained with an OAuth2 code + flow. An instance of it would be used as a dependency. + """ + + def __init__( + self, + authorizationUrl: str, + tokenUrl: Annotated[ + str, + Doc( + """ + The URL to obtain the OAuth2 token. + """ + ), + ], + refreshUrl: Annotated[ + Optional[str], + Doc( + """ + The URL to refresh the token and obtain a new one. + """ + ), + ] = None, + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + scopes: Annotated[ + Optional[Dict[str, str]], + Doc( + """ + The OAuth2 scopes that would be required by the *path operations* that + use this dependency. + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if no HTTP Authorization header is provided, required for + OAuth2 authentication, it will automatically cancel the request and + send the client an error. + + If `auto_error` is set to `False`, when the HTTP Authorization header + is not available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, with OAuth2 + or in a cookie). + """ + ), + ] = True, + ): + if not scopes: + scopes = {} + flows = OAuthFlowsModel( + authorizationCode=cast( + Any, + { + "authorizationUrl": authorizationUrl, + "tokenUrl": tokenUrl, + "refreshUrl": refreshUrl, + "scopes": scopes, + }, + ) + ) + super().__init__( + flows=flows, + scheme_name=scheme_name, + description=description, + auto_error=auto_error, + ) + + async def __call__(self, request: Request) -> Optional[str]: + authorization = request.headers.get("Authorization") + scheme, param = get_authorization_scheme_param(authorization) + if not authorization or scheme.lower() != "bearer": + if self.auto_error: + raise HTTPException( + status_code=HTTP_401_UNAUTHORIZED, + detail="Not authenticated", + headers={"WWW-Authenticate": "Bearer"}, + ) + else: + return None # pragma: nocover + return param + + +class SecurityScopes: + """ + This is a special class that you can define in a parameter in a dependency to + obtain the OAuth2 scopes required by all the dependencies in the same chain. + + This way, multiple dependencies can have different scopes, even when used in the + same *path operation*. And with this, you can access all the scopes required in + all those dependencies in a single place. + + Read more about it in the + [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/). + """ + + def __init__( + self, + scopes: Annotated[ + Optional[List[str]], + Doc( + """ + This will be filled by FastAPI. + """ + ), + ] = None, + ): + self.scopes: Annotated[ + List[str], + Doc( + """ + The list of all the scopes required by dependencies. + """ + ), + ] = scopes or [] + self.scope_str: Annotated[ + str, + Doc( + """ + All the scopes required by all the dependencies in a single string + separated by spaces, as defined in the OAuth2 specification. + """ + ), + ] = " ".join(self.scopes) diff --git a/venv/lib/python3.11/site-packages/fastapi/security/open_id_connect_url.py b/venv/lib/python3.11/site-packages/fastapi/security/open_id_connect_url.py new file mode 100644 index 0000000..c8cceb9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/open_id_connect_url.py @@ -0,0 +1,84 @@ +from typing import Optional + +from fastapi.openapi.models import OpenIdConnect as OpenIdConnectModel +from fastapi.security.base import SecurityBase +from starlette.exceptions import HTTPException +from starlette.requests import Request +from starlette.status import HTTP_403_FORBIDDEN +from typing_extensions import Annotated, Doc + + +class OpenIdConnect(SecurityBase): + """ + OpenID Connect authentication class. An instance of it would be used as a + dependency. + """ + + def __init__( + self, + *, + openIdConnectUrl: Annotated[ + str, + Doc( + """ + The OpenID Connect URL. + """ + ), + ], + scheme_name: Annotated[ + Optional[str], + Doc( + """ + Security scheme name. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + description: Annotated[ + Optional[str], + Doc( + """ + Security scheme description. + + It will be included in the generated OpenAPI (e.g. visible at `/docs`). + """ + ), + ] = None, + auto_error: Annotated[ + bool, + Doc( + """ + By default, if no HTTP Authorization header is provided, required for + OpenID Connect authentication, it will automatically cancel the request + and send the client an error. + + If `auto_error` is set to `False`, when the HTTP Authorization header + is not available, instead of erroring out, the dependency result will + be `None`. + + This is useful when you want to have optional authentication. + + It is also useful when you want to have authentication that can be + provided in one of multiple optional ways (for example, with OpenID + Connect or in a cookie). + """ + ), + ] = True, + ): + self.model = OpenIdConnectModel( + openIdConnectUrl=openIdConnectUrl, description=description + ) + self.scheme_name = scheme_name or self.__class__.__name__ + self.auto_error = auto_error + + async def __call__(self, request: Request) -> Optional[str]: + authorization = request.headers.get("Authorization") + if not authorization: + if self.auto_error: + raise HTTPException( + status_code=HTTP_403_FORBIDDEN, detail="Not authenticated" + ) + else: + return None + return authorization diff --git a/venv/lib/python3.11/site-packages/fastapi/security/utils.py b/venv/lib/python3.11/site-packages/fastapi/security/utils.py new file mode 100644 index 0000000..fa7a450 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/security/utils.py @@ -0,0 +1,10 @@ +from typing import Optional, Tuple + + +def get_authorization_scheme_param( + authorization_header_value: Optional[str], +) -> Tuple[str, str]: + if not authorization_header_value: + return "", "" + scheme, _, param = authorization_header_value.partition(" ") + return scheme, param diff --git a/venv/lib/python3.11/site-packages/fastapi/staticfiles.py b/venv/lib/python3.11/site-packages/fastapi/staticfiles.py new file mode 100644 index 0000000..299015d --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/staticfiles.py @@ -0,0 +1 @@ +from starlette.staticfiles import StaticFiles as StaticFiles # noqa diff --git a/venv/lib/python3.11/site-packages/fastapi/templating.py b/venv/lib/python3.11/site-packages/fastapi/templating.py new file mode 100644 index 0000000..0cb8684 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/templating.py @@ -0,0 +1 @@ +from starlette.templating import Jinja2Templates as Jinja2Templates # noqa diff --git a/venv/lib/python3.11/site-packages/fastapi/testclient.py b/venv/lib/python3.11/site-packages/fastapi/testclient.py new file mode 100644 index 0000000..4012406 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/testclient.py @@ -0,0 +1 @@ +from starlette.testclient import TestClient as TestClient # noqa diff --git a/venv/lib/python3.11/site-packages/fastapi/types.py b/venv/lib/python3.11/site-packages/fastapi/types.py new file mode 100644 index 0000000..3205654 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/types.py @@ -0,0 +1,10 @@ +import types +from enum import Enum +from typing import Any, Callable, Dict, Set, Type, TypeVar, Union + +from pydantic import BaseModel + +DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any]) +UnionType = getattr(types, "UnionType", Union) +ModelNameMap = Dict[Union[Type[BaseModel], Type[Enum]], str] +IncEx = Union[Set[int], Set[str], Dict[int, Any], Dict[str, Any]] diff --git a/venv/lib/python3.11/site-packages/fastapi/utils.py b/venv/lib/python3.11/site-packages/fastapi/utils.py new file mode 100644 index 0000000..4c7350f --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/utils.py @@ -0,0 +1,220 @@ +import re +import warnings +from dataclasses import is_dataclass +from typing import ( + TYPE_CHECKING, + Any, + Dict, + MutableMapping, + Optional, + Set, + Type, + Union, + cast, +) +from weakref import WeakKeyDictionary + +import fastapi +from fastapi._compat import ( + PYDANTIC_V2, + BaseConfig, + ModelField, + PydanticSchemaGenerationError, + Undefined, + UndefinedType, + Validator, + lenient_issubclass, +) +from fastapi.datastructures import DefaultPlaceholder, DefaultType +from pydantic import BaseModel, create_model +from pydantic.fields import FieldInfo +from typing_extensions import Literal + +if TYPE_CHECKING: # pragma: nocover + from .routing import APIRoute + +# Cache for `create_cloned_field` +_CLONED_TYPES_CACHE: MutableMapping[Type[BaseModel], Type[BaseModel]] = ( + WeakKeyDictionary() +) + + +def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool: + if status_code is None: + return True + # Ref: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#patterned-fields-1 + if status_code in { + "default", + "1XX", + "2XX", + "3XX", + "4XX", + "5XX", + }: + return True + current_status_code = int(status_code) + return not (current_status_code < 200 or current_status_code in {204, 205, 304}) + + +def get_path_param_names(path: str) -> Set[str]: + return set(re.findall("{(.*?)}", path)) + + +def create_model_field( + name: str, + type_: Any, + class_validators: Optional[Dict[str, Validator]] = None, + default: Optional[Any] = Undefined, + required: Union[bool, UndefinedType] = Undefined, + model_config: Type[BaseConfig] = BaseConfig, + field_info: Optional[FieldInfo] = None, + alias: Optional[str] = None, + mode: Literal["validation", "serialization"] = "validation", +) -> ModelField: + class_validators = class_validators or {} + if PYDANTIC_V2: + field_info = field_info or FieldInfo( + annotation=type_, default=default, alias=alias + ) + else: + field_info = field_info or FieldInfo() + kwargs = {"name": name, "field_info": field_info} + if PYDANTIC_V2: + kwargs.update({"mode": mode}) + else: + kwargs.update( + { + "type_": type_, + "class_validators": class_validators, + "default": default, + "required": required, + "model_config": model_config, + "alias": alias, + } + ) + try: + return ModelField(**kwargs) # type: ignore[arg-type] + except (RuntimeError, PydanticSchemaGenerationError): + raise fastapi.exceptions.FastAPIError( + "Invalid args for response field! Hint: " + f"check that {type_} is a valid Pydantic field type. " + "If you are using a return type annotation that is not a valid Pydantic " + "field (e.g. Union[Response, dict, None]) you can disable generating the " + "response model from the type annotation with the path operation decorator " + "parameter response_model=None. Read more: " + "https://fastapi.tiangolo.com/tutorial/response-model/" + ) from None + + +def create_cloned_field( + field: ModelField, + *, + cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None, +) -> ModelField: + if PYDANTIC_V2: + return field + # cloned_types caches already cloned types to support recursive models and improve + # performance by avoiding unnecessary cloning + if cloned_types is None: + cloned_types = _CLONED_TYPES_CACHE + + original_type = field.type_ + if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"): + original_type = original_type.__pydantic_model__ + use_type = original_type + if lenient_issubclass(original_type, BaseModel): + original_type = cast(Type[BaseModel], original_type) + use_type = cloned_types.get(original_type) + if use_type is None: + use_type = create_model(original_type.__name__, __base__=original_type) + cloned_types[original_type] = use_type + for f in original_type.__fields__.values(): + use_type.__fields__[f.name] = create_cloned_field( + f, cloned_types=cloned_types + ) + new_field = create_model_field(name=field.name, type_=use_type) + new_field.has_alias = field.has_alias # type: ignore[attr-defined] + new_field.alias = field.alias # type: ignore[misc] + new_field.class_validators = field.class_validators # type: ignore[attr-defined] + new_field.default = field.default # type: ignore[misc] + new_field.required = field.required # type: ignore[misc] + new_field.model_config = field.model_config # type: ignore[attr-defined] + new_field.field_info = field.field_info + new_field.allow_none = field.allow_none # type: ignore[attr-defined] + new_field.validate_always = field.validate_always # type: ignore[attr-defined] + if field.sub_fields: # type: ignore[attr-defined] + new_field.sub_fields = [ # type: ignore[attr-defined] + create_cloned_field(sub_field, cloned_types=cloned_types) + for sub_field in field.sub_fields # type: ignore[attr-defined] + ] + if field.key_field: # type: ignore[attr-defined] + new_field.key_field = create_cloned_field( # type: ignore[attr-defined] + field.key_field, # type: ignore[attr-defined] + cloned_types=cloned_types, + ) + new_field.validators = field.validators # type: ignore[attr-defined] + new_field.pre_validators = field.pre_validators # type: ignore[attr-defined] + new_field.post_validators = field.post_validators # type: ignore[attr-defined] + new_field.parse_json = field.parse_json # type: ignore[attr-defined] + new_field.shape = field.shape # type: ignore[attr-defined] + new_field.populate_validators() # type: ignore[attr-defined] + return new_field + + +def generate_operation_id_for_path( + *, name: str, path: str, method: str +) -> str: # pragma: nocover + warnings.warn( + "fastapi.utils.generate_operation_id_for_path() was deprecated, " + "it is not used internally, and will be removed soon", + DeprecationWarning, + stacklevel=2, + ) + operation_id = f"{name}{path}" + operation_id = re.sub(r"\W", "_", operation_id) + operation_id = f"{operation_id}_{method.lower()}" + return operation_id + + +def generate_unique_id(route: "APIRoute") -> str: + operation_id = f"{route.name}{route.path_format}" + operation_id = re.sub(r"\W", "_", operation_id) + assert route.methods + operation_id = f"{operation_id}_{list(route.methods)[0].lower()}" + return operation_id + + +def deep_dict_update(main_dict: Dict[Any, Any], update_dict: Dict[Any, Any]) -> None: + for key, value in update_dict.items(): + if ( + key in main_dict + and isinstance(main_dict[key], dict) + and isinstance(value, dict) + ): + deep_dict_update(main_dict[key], value) + elif ( + key in main_dict + and isinstance(main_dict[key], list) + and isinstance(update_dict[key], list) + ): + main_dict[key] = main_dict[key] + update_dict[key] + else: + main_dict[key] = value + + +def get_value_or_default( + first_item: Union[DefaultPlaceholder, DefaultType], + *extra_items: Union[DefaultPlaceholder, DefaultType], +) -> Union[DefaultPlaceholder, DefaultType]: + """ + Pass items or `DefaultPlaceholder`s by descending priority. + + The first one to _not_ be a `DefaultPlaceholder` will be returned. + + Otherwise, the first item (a `DefaultPlaceholder`) will be returned. + """ + items = (first_item,) + extra_items + for item in items: + if not isinstance(item, DefaultPlaceholder): + return item + return first_item diff --git a/venv/lib/python3.11/site-packages/fastapi/websockets.py b/venv/lib/python3.11/site-packages/fastapi/websockets.py new file mode 100644 index 0000000..55a4ac4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/fastapi/websockets.py @@ -0,0 +1,3 @@ +from starlette.websockets import WebSocket as WebSocket # noqa +from starlette.websockets import WebSocketDisconnect as WebSocketDisconnect # noqa +from starlette.websockets import WebSocketState as WebSocketState # noqa diff --git a/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/LICENSE.txt b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..8f080ea --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nathaniel J. Smith and other 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.11/site-packages/h11-0.14.0.dist-info/METADATA b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/METADATA new file mode 100644 index 0000000..cf12a82 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/METADATA @@ -0,0 +1,193 @@ +Metadata-Version: 2.1 +Name: h11 +Version: 0.14.0 +Summary: A pure-Python, bring-your-own-I/O implementation of HTTP/1.1 +Home-page: https://github.com/python-hyper/h11 +Author: Nathaniel J. Smith +Author-email: njs@pobox.com +License: MIT +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +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: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: System :: Networking +Requires-Python: >=3.7 +License-File: LICENSE.txt +Requires-Dist: typing-extensions ; python_version < "3.8" + +h11 +=== + +.. image:: https://travis-ci.org/python-hyper/h11.svg?branch=master + :target: https://travis-ci.org/python-hyper/h11 + :alt: Automated test status + +.. image:: https://codecov.io/gh/python-hyper/h11/branch/master/graph/badge.svg + :target: https://codecov.io/gh/python-hyper/h11 + :alt: Test coverage + +.. image:: https://readthedocs.org/projects/h11/badge/?version=latest + :target: http://h11.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +This is a little HTTP/1.1 library written from scratch in Python, +heavily inspired by `hyper-h2 `_. + +It's a "bring-your-own-I/O" library; h11 contains no IO code +whatsoever. This means you can hook h11 up to your favorite network +API, and that could be anything you want: synchronous, threaded, +asynchronous, or your own implementation of `RFC 6214 +`_ -- h11 won't judge you. +(Compare this to the current state of the art, where every time a `new +network API `_ comes along then someone +gets to start over reimplementing the entire HTTP protocol from +scratch.) Cory Benfield made an `excellent blog post describing the +benefits of this approach +`_, or if you like video +then here's his `PyCon 2016 talk on the same theme +`_. + +This also means that h11 is not immediately useful out of the box: +it's a toolkit for building programs that speak HTTP, not something +that could directly replace ``requests`` or ``twisted.web`` or +whatever. But h11 makes it much easier to implement something like +``requests`` or ``twisted.web``. + +At a high level, working with h11 goes like this: + +1) First, create an ``h11.Connection`` object to track the state of a + single HTTP/1.1 connection. + +2) When you read data off the network, pass it to + ``conn.receive_data(...)``; you'll get back a list of objects + representing high-level HTTP "events". + +3) When you want to send a high-level HTTP event, create the + corresponding "event" object and pass it to ``conn.send(...)``; + this will give you back some bytes that you can then push out + through the network. + +For example, a client might instantiate and then send a +``h11.Request`` object, then zero or more ``h11.Data`` objects for the +request body (e.g., if this is a POST), and then a +``h11.EndOfMessage`` to indicate the end of the message. Then the +server would then send back a ``h11.Response``, some ``h11.Data``, and +its own ``h11.EndOfMessage``. If either side violates the protocol, +you'll get a ``h11.ProtocolError`` exception. + +h11 is suitable for implementing both servers and clients, and has a +pleasantly symmetric API: the events you send as a client are exactly +the ones that you receive as a server and vice-versa. + +`Here's an example of a tiny HTTP client +`_ + +It also has `a fine manual `_. + +FAQ +--- + +*Whyyyyy?* + +I wanted to play with HTTP in `Curio +`__ and `Trio +`__, which at the time didn't have any +HTTP libraries. So I thought, no big deal, Python has, like, a dozen +different implementations of HTTP, surely I can find one that's +reusable. I didn't find one, but I did find Cory's call-to-arms +blog-post. So I figured, well, fine, if I have to implement HTTP from +scratch, at least I can make sure no-one *else* has to ever again. + +*Should I use it?* + +Maybe. You should be aware that it's a very young project. But, it's +feature complete and has an exhaustive test-suite and complete docs, +so the next step is for people to try using it and see how it goes +:-). If you do then please let us know -- if nothing else we'll want +to talk to you before making any incompatible changes! + +*What are the features/limitations?* + +Roughly speaking, it's trying to be a robust, complete, and non-hacky +implementation of the first "chapter" of the HTTP/1.1 spec: `RFC 7230: +HTTP/1.1 Message Syntax and Routing +`_. That is, it mostly focuses on +implementing HTTP at the level of taking bytes on and off the wire, +and the headers related to that, and tries to be anal about spec +conformance. It doesn't know about higher-level concerns like URL +routing, conditional GETs, cross-origin cookie policies, or content +negotiation. But it does know how to take care of framing, +cross-version differences in keep-alive handling, and the "obsolete +line folding" rule, so you can focus your energies on the hard / +interesting parts for your application, and it tries to support the +full specification in the sense that any useful HTTP/1.1 conformant +application should be able to use h11. + +It's pure Python, and has no dependencies outside of the standard +library. + +It has a test suite with 100.0% coverage for both statements and +branches. + +Currently it supports Python 3 (testing on 3.7-3.10) and PyPy 3. +The last Python 2-compatible version was h11 0.11.x. +(Originally it had a Cython wrapper for `http-parser +`_ and a beautiful nested state +machine implemented with ``yield from`` to postprocess the output. But +I had to take these out -- the new *parser* needs fewer lines-of-code +than the old *parser wrapper*, is written in pure Python, uses no +exotic language syntax, and has more features. It's sad, really; that +old state machine was really slick. I just need a few sentences here +to mourn that.) + +I don't know how fast it is. I haven't benchmarked or profiled it yet, +so it's probably got a few pointless hot spots, and I've been trying +to err on the side of simplicity and robustness instead of +micro-optimization. But at the architectural level I tried hard to +avoid fundamentally bad decisions, e.g., I believe that all the +parsing algorithms remain linear-time even in the face of pathological +input like slowloris, and there are no byte-by-byte loops. (I also +believe that it maintains bounded memory usage in the face of +arbitrary/pathological input.) + +The whole library is ~800 lines-of-code. You can read and understand +the whole thing in less than an hour. Most of the energy invested in +this so far has been spent on trying to keep things simple by +minimizing special-cases and ad hoc state manipulation; even though it +is now quite small and simple, I'm still annoyed that I haven't +figured out how to make it even smaller and simpler. (Unfortunately, +HTTP does not lend itself to simplicity.) + +The API is ~feature complete and I don't expect the general outlines +to change much, but you can't judge an API's ergonomics until you +actually document and use it, so I'd expect some changes in the +details. + +*How do I try it?* + +.. code-block:: sh + + $ pip install h11 + $ git clone git@github.com:python-hyper/h11 + $ cd h11/examples + $ python basic-client.py + +and go from there. + +*License?* + +MIT + +*Code of conduct?* + +Contributors are requested to follow our `code of conduct +`_ in +all project spaces. diff --git a/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/RECORD b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/RECORD new file mode 100644 index 0000000..a055008 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/RECORD @@ -0,0 +1,52 @@ +h11-0.14.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +h11-0.14.0.dist-info/LICENSE.txt,sha256=N9tbuFkm2yikJ6JYZ_ELEjIAOuob5pzLhRE4rbjm82E,1124 +h11-0.14.0.dist-info/METADATA,sha256=B7pZ0m7WBXNs17vl6hUH9bJTL9s37DaGvY31w7jNxSg,8175 +h11-0.14.0.dist-info/RECORD,, +h11-0.14.0.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +h11-0.14.0.dist-info/top_level.txt,sha256=F7dC4jl3zeh8TGHEPaWJrMbeuoWbS379Gwdi-Yvdcis,4 +h11/__init__.py,sha256=iO1KzkSO42yZ6ffg-VMgbx_ZVTWGUY00nRYEWn-s3kY,1507 +h11/__pycache__/__init__.cpython-311.pyc,, +h11/__pycache__/_abnf.cpython-311.pyc,, +h11/__pycache__/_connection.cpython-311.pyc,, +h11/__pycache__/_events.cpython-311.pyc,, +h11/__pycache__/_headers.cpython-311.pyc,, +h11/__pycache__/_readers.cpython-311.pyc,, +h11/__pycache__/_receivebuffer.cpython-311.pyc,, +h11/__pycache__/_state.cpython-311.pyc,, +h11/__pycache__/_util.cpython-311.pyc,, +h11/__pycache__/_version.cpython-311.pyc,, +h11/__pycache__/_writers.cpython-311.pyc,, +h11/_abnf.py,sha256=ybixr0xsupnkA6GFAyMubuXF6Tc1lb_hF890NgCsfNc,4815 +h11/_connection.py,sha256=eS2sorMD0zKLCFiB9lW9W9F_Nzny2tjHa4e6s1ujr1c,26539 +h11/_events.py,sha256=LEfuvg1AbhHaVRwxCd0I-pFn9-ezUOaoL8o2Kvy1PBA,11816 +h11/_headers.py,sha256=RqB8cd8CN0blYPzcLe5qeCh-phv6D1U_CHj4hs67lgQ,10230 +h11/_readers.py,sha256=EbSed0jzwVUiD1nOPAeUcVE4Flf3wXkxfb8c06-OTBM,8383 +h11/_receivebuffer.py,sha256=xrspsdsNgWFxRfQcTXxR8RrdjRXXTK0Io5cQYWpJ1Ws,5252 +h11/_state.py,sha256=k1VL6SDbaPkSrZ-49ewCXDpuiUS69_46YhbWjuV1qEY,13300 +h11/_util.py,sha256=LWkkjXyJaFlAy6Lt39w73UStklFT5ovcvo0TkY7RYuk,4888 +h11/_version.py,sha256=LVyTdiZRzIIEv79UyOgbM5iUrJUllEzlCWaJEYBY1zc,686 +h11/_writers.py,sha256=oFKm6PtjeHfbj4RLX7VB7KDc1gIY53gXG3_HR9ltmTA,5081 +h11/py.typed,sha256=sow9soTwP9T_gEAQSVh7Gb8855h04Nwmhs2We-JRgZM,7 +h11/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +h11/tests/__pycache__/__init__.cpython-311.pyc,, +h11/tests/__pycache__/helpers.cpython-311.pyc,, +h11/tests/__pycache__/test_against_stdlib_http.cpython-311.pyc,, +h11/tests/__pycache__/test_connection.cpython-311.pyc,, +h11/tests/__pycache__/test_events.cpython-311.pyc,, +h11/tests/__pycache__/test_headers.cpython-311.pyc,, +h11/tests/__pycache__/test_helpers.cpython-311.pyc,, +h11/tests/__pycache__/test_io.cpython-311.pyc,, +h11/tests/__pycache__/test_receivebuffer.cpython-311.pyc,, +h11/tests/__pycache__/test_state.cpython-311.pyc,, +h11/tests/__pycache__/test_util.cpython-311.pyc,, +h11/tests/data/test-file,sha256=ZJ03Rqs98oJw29OHzJg7LlMzyGQaRAY0r3AqBeM2wVU,65 +h11/tests/helpers.py,sha256=a1EVG_p7xU4wRsa3tMPTRxuaKCmretok9sxXWvqfmQA,3355 +h11/tests/test_against_stdlib_http.py,sha256=cojCHgHXFQ8gWhNlEEwl3trmOpN-5uDukRoHnElqo3A,3995 +h11/tests/test_connection.py,sha256=ZbPLDPclKvjgjAhgk-WlCPBaf17c4XUIV2tpaW08jOI,38720 +h11/tests/test_events.py,sha256=LPVLbcV-NvPNK9fW3rraR6Bdpz1hAlsWubMtNaJ5gHg,4657 +h11/tests/test_headers.py,sha256=qd8T1Zenuz5GbD6wklSJ5G8VS7trrYgMV0jT-SMvqg8,5612 +h11/tests/test_helpers.py,sha256=kAo0CEM4LGqmyyP2ZFmhsyq3UFJqoFfAbzu3hbWreRM,794 +h11/tests/test_io.py,sha256=uCZVnjarkRBkudfC1ij-KSCQ71XWJhnkgkgWWkKgYPQ,16386 +h11/tests/test_receivebuffer.py,sha256=3jGbeJM36Akqg_pAhPb7XzIn2NS6RhPg-Ryg8Eu6ytk,3454 +h11/tests/test_state.py,sha256=rqll9WqFsJPE0zSrtCn9LH659mPKsDeXZ-DwXwleuBQ,8928 +h11/tests/test_util.py,sha256=VO5L4nSFe4pgtSwKuv6u_6l0H7UeizF5WKuHTWreg70,2970 diff --git a/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/WHEEL b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/WHEEL new file mode 100644 index 0000000..5bad85f --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/top_level.txt b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/top_level.txt new file mode 100644 index 0000000..0d24def --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11-0.14.0.dist-info/top_level.txt @@ -0,0 +1 @@ +h11 diff --git a/venv/lib/python3.11/site-packages/h11/__init__.py b/venv/lib/python3.11/site-packages/h11/__init__.py new file mode 100644 index 0000000..989e92c --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/__init__.py @@ -0,0 +1,62 @@ +# A highish-level implementation of the HTTP/1.1 wire protocol (RFC 7230), +# containing no networking code at all, loosely modelled on hyper-h2's generic +# implementation of HTTP/2 (and in particular the h2.connection.H2Connection +# class). There's still a bunch of subtle details you need to get right if you +# want to make this actually useful, because it doesn't implement all the +# semantics to check that what you're asking to write to the wire is sensible, +# but at least it gets you out of dealing with the wire itself. + +from h11._connection import Connection, NEED_DATA, PAUSED +from h11._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from h11._state import ( + CLIENT, + CLOSED, + DONE, + ERROR, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from h11._util import LocalProtocolError, ProtocolError, RemoteProtocolError +from h11._version import __version__ + +PRODUCT_ID = "python-h11/" + __version__ + + +__all__ = ( + "Connection", + "NEED_DATA", + "PAUSED", + "ConnectionClosed", + "Data", + "EndOfMessage", + "Event", + "InformationalResponse", + "Request", + "Response", + "CLIENT", + "CLOSED", + "DONE", + "ERROR", + "IDLE", + "MUST_CLOSE", + "SEND_BODY", + "SEND_RESPONSE", + "SERVER", + "SWITCHED_PROTOCOL", + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", +) diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..030d331e147771575ef5d776d905e8ca9ad28667 GIT binary patch literal 1315 zcmc(d&u`N(6vv(ZNZO=Xf354*G2k#Edf1|g69^%VCSsA=rb;>xM#2iMw-w@~Bw45J zwEqH*+z|iGxFMgACLtj%m3G?+JKI1*s>B76IG;Q}+t1(U=Z~r?1NOZ9_G9-n3&1Jw zTs^5v&tB z$O>Fxwuo1bm@0U4D8XC9oCBKq?_6#(P32bL`*;wK0-xr)hM^;Uv%g8j-sZMr=uL^1 zeott5L4=1iqr0(73x+?mb~-qU++9qw#svE@t(pE#5E7S%b3GeJMF#?;#et#!;NTYcm_GyAPA)U&O=)w0@D?rb}K zlq{op$LQ+lv86w!YGT@k)3dscK}E-~pBgqTUo2;tT?JriSK7hA^?G3t2ZO*f!Y~M_ zdc9k216 zp^-m|5n3M~p64EtV7Tw$N8ue7SzupeGEUQiAWSPjcyI#l&uY_DPDo9`zd)tHBmYk{ mfY1?6KzmmE0#;A1x36mB{fp1)-D7zwE-I;GiNE10JJO#)`ApXU literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_abnf.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_abnf.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c6150f0cb02804d64b41e965572642d45896f3d GIT binary patch literal 1820 zcma)+Pi)&%9LJv%+xchbU(3?23|cx!osuS9#U@JEQef+PDU~*<%uQ)8`AR#m)BtYUYqzPKl14tYO;xHuc3l0X3QHSGmBIHc}3jB)5nCnZgG>%_m^(B&WMIstDhpC(c(PB z3^$K&H-~TCxwBYs&r}U#OK4zCmsMqY87e84#=MC$-*)#mu~Ai}>83xoxIx!xh*||3 z(@hP3RL8m@_%>`dJHxfiuotO0(K25g@yfmLXCSDWpswnIfp?(3oVjrRoOg$Ah(=u( z)>H|K=`dOxXy*|c7IjD(vT$c%tE!1Q=mC1g+uJ$3&~&u6xxhY#bqcKjNQy`{aS{ksQu zeanhDVUp@~5J|Dm;ErA=LQ+GnIRqy&FFmMyA%7`%ID?2_oy#biu;`=I@PmQF)Nngh zgz>QQu=1V!NcJr&ew28_VjPmBF1gVzK=8~ZH%`tqa}azm`}OuWyWj41IKAK(QR1Ro z*41{haOl3@h4DD^IP+`&@BO|7Wsza3=%6sgJxiio(Mg4=>#lhnWSf}$Df=_`3)kU< zz>L#}qJ0+aFbJezUpZvCHhUGu-rU~Y{`|qbZ-K@PVtcHJLk6fm2L-6qKdFpEkreGF cPCGP;r9a7j%6-N;p;M=uxW!nE)(<`WAFZ(tWdHyG literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_connection.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_connection.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52859141a94b365c22001903bc1d73b3e3d090e2 GIT binary patch literal 24306 zcmch9d2Ae4nqT$BZnB%|7Vn!SN+Q`34^g5HQ$9u#scR%srl_&qaolXNieyWDaH^_B ziKfP$fj8i6gk54{$6Un9^d_>yS=)$!>>vs-0~otIfdAM4)kGO;bRa~FzyX~7hla+$ zVEzd5``+uWu5MBqJ3C3S__~gFzwdqT_Z_ePLv?kPfa8t-`HyoS&k4f+pqs+s&0jqE zl}!-d7bHQl#e}#mWQ*HF_P8VDh&w~hxGUs}SA;6!?vOj~33=j`p-P(|*(FD;D(($= zbUGc6^SA2J9cYIH1Pke7^FN^Pq zb;o-`J@MX9Z#)z3+^DP^~OxOivHv*fx$YCzscSp6DNzow7us5$=gH9smfUlxKbU(s!_GUqsvxRvvq zio{}(t1&s}oQbGf&N&*LL3kmGYtO`j7ELB1v7BovwLnp(ZY{_;*OdgGeg!%Zg6>@4 zR5Fo}XDH&SSW=ZGWD(IKIp0`9nwY&Pt7>EpX~u5I2`yKDE-{-_;t`(hq^vF^6RMnZ zPs%?`$y8$DQP7bK%*k4KCK-=M!t-)Ol9gQJd_)b)Hy2P^c<8_Zyi91(L`u#D)Uv2S zJMtVmF*-JRIp>{Zsa2|b(3Y#7lxO7V4f$khc2-t`RXKn7@+;@2PMr;(niwA+J2h2& zaOKjON#v2MICbIN*f?Gkn|fJ`Xy}j8iSaSCZE|vAGFN}`+?lgeh0HEZPE1Xlnz)dw zygW8O8a_EO`dY5y^4R1L#wK$+d4Xf2;X*7lx8_1}CK9`(B(>yBGB&0tNhMc1DaVtV zT>8*+89f2#N}`}R}~J&lTs>1*S>K0hp9-6 zzxjpmg!1|Qg~1yUWpHtEaS)Zi7L{)#V<{T%K~TVr!C3U_;KD6!KAAW)Ff=r%qSpNj zk(uit5_NDMPiR#0^fa(=i&cOHy~z8CAHmz^U)Je)dsI1yXDkK=w=ynkk(pRTRlh?U z_alRGrJu4HqJU+1h_2`j3;O6{*nCOPqr&$DA?K1AT~{cwmQoTkh0er#!G(VZ{-0b! z@V=l~-YpB)%sa_eI!kZcB>S@MhM<6JUKTXUC4Vdnl2dYhggif{eAywnuCrerTdKgI zxyPRn8!vX_6Ut+T=H}^~Z(h?D!Z$!E7?CHG&CtNmRM4T+;WFpu6HU#zG4~>xrho#D z(u=BMZYuE;QBG>Di3C-*ETeuh?)O(cMSbyR6s0GR#IIw?pB~A&jw| zPfBczW=y7rqRfu|YjkQ^N83KavyaWr)-35XC(`DRS^Et^wVxM$Vk;S@^3;|TDM5K| z*>FjXPt%X}`|uq*Ry#=t|gaLc&f%XpJj5uQL+J z*RHZqV}W9s#38xMh{(QdSG>!1$unom*N3%Essu?rEsv_QJRHjorAhK?)s`|HlCQWB zmG~|^QWdzt#F}QYR;c8ILsTNs?=-|2cKHi;j2mMR(Mv4#L)_63NK&AzuJW^ zcw6{phu{mWx_)~6&hfiPKRm0q^y}W@`AwVP@vV&g_|13Td~aTNci?>N+iCdP(=EDh zKhCVbJ>9tB@74Xi*+55n-$tNM5A@xyec&>VozsUVaBi^h^HcnnKSTJqcE4V`f72rb z>J7h`KDFWR(F^A{6++9t^}V0;>(5=xG>;q2u%l@?5@tNe^>fi`t=R}kX|^m z{*INmkf^aIow|2hKXNA1aMoxz`}RcE-LNUxTrXw=;)jRQZ{7c)(eqqp_lU83MDKcD z_rIWfUO+OliE{;}LRER}@6`RBjCIVQzs$p%zk2e&K`YjEF65A%vtYWiORgx=w&VZ= z1G}BAkSgABg*Bw^Q07*PvCkr7?zR++uxNOf&0YK)JP2kahtqf9sw{n@Y>(V_1(dY-9b^ zE_cZ2GfPQ!g3V=P)hRW~9r?a$LK{WYw?VE!PwgtE#9deMZq{MBwoA=Owfj4#YC)Pl*DYJ#mc(mAydI2yJAQkm4mpTg1TmJKxZfwaz;C;hAjmRu5;NgM zLQG!021G4_Ges8ER1DxeF(+#CvPjHL7L&7LBq5%inz|$wQNTb|6|t%l%A7jFuIMhA zQo>3yCXa~cX2n~{RF5Ky(KrN$I76&+Vnm#YMRDCHE&!s5BN7CKk!hg50gkYz2awXt zjRi+SWm9mvawswH{J zH)mv7lBGV%B_WOwm>QW*$Tv0KDbuWNq7sR!rIi>#%8}`91d&2F=RAdR&ow`_yOm=g zxbYbiF5%9EZT|}^+WW$?eOU;b%yQXg1q)?R&8Bo|1P$_sWJ_CsS>fqc_)!W*eqvj; zp+plxEekdP7Hg@1DAm@I5xb(0d%|apX?>%SjFLY}nF?Zg3U8K$v;~G0o}$iz1=I-| zL5loQiu;jQVL?Nhr{-nWR}!?QLQaCPB`*`=Y3-I+xGXMTDA8;gBorYWD8!UdgD_z) zcCb4_Nc@gs5>(=M0+^3ud}%iq;$=zX^Il9UBA>f`Vj`)DZ|+iVpAOdLTEb5!s5a!N zbRo!9{U8!c$y{Qt;OYhC2kZq%J<3^x1W62er}`v+~>WS_RB{5({-!6>c;09{Pp^RH#Qwi{>w~wbo^6{ILQfxE?cUrW z3?HMb&g_BV!n;H4$)N6`lLI|)5c8mJqW>qu2+G7ki`;z;iyuEq`2r}^w)E2zq69q{ zWaNl)3oQ1!JTk&pJX$AkyvYf7M0}nPC0{FF?8}oep7S*-|NM3_@nu;SM-+K>WSWs; ze>^fX4;DTxf&xSdVs|vAS{5*(1FDMh&r#W21xus;!lumPR;6ZhdQeEou(Z=c3OwfD zP&A@vhzvDCpl)^a-3vxtPsZPC0R4M;20^o{xSzf$}L1Zh3HX{;u@!y%!9~D4wA|e(xl{L+^}F zO#M-N=ymF=@*eVXe#QH!!O};T=f+cd=_SK|NcS9iMlX@xtdxeV%VtVQR#++NvhWMr zI0ltfl<{|YyDINO)oz7BKTlU%5^Z5 z6XvNs@?$WM6PhN+7c@~z0#^c!5`wpY{QUGK#uO0~^5PcoY0lZ1TQf1)!nFWGuO_wm zJlu!;AOY+WW@pnr3jE2TKk3h>c`@FBRE4X-1i1v>(my zUx+Tqfa>6O*4X1gw-Uv075Nx!8Cpcq!VH?Q%tsPX zokLMeD?+X+8I$-M)vBmfG`w7Dwakk0QvN$4sKiaNP&5e*Eo*x|=rdaSGxY;T{lH2U zV89*UL(kp~&)$ru2UvnYLFewml3dqh)Q;$${E5g9J>46g?(|Z|bI|Y{)C(t@N;xO3 z0VOJ2b3*-V)Zn|X*|&i*|ImcmIuS5s%n5~J&12bKiU=@efLoOxB0|trK3vrcN^%B9 zuCPoN8zn`N9BeFX(vBj4GQGZe`w{8d@L<8pczO*F zt>=HB>zOuk`<{P{a>{!C+3MRGD4nPtRih>9VwPuqDptr;)Xu2VybkvHNVSj41><`uh^1uhN6+JBIr>j=$gbA$&!P3k}`%|kP#Q%Jj5={`0k z1e>6l@+jnO`!$p5Bzvg=MEN%55O~ZV<>g4iZJ2$mayMF353XZM+l7?$Th4Wm*3!Re zvd(Tfkh?{TP@coGvsBJU%byXutml2!o(J?WWq;C|Tr+zYEqeXi=BjlS8=&neUe7u( zubDVF{bE0n3M0{LlszTJO{D^WXq6Tsw;0TXN zJ#67&ixJ^_#Y@5S6wFX?0zs~|P;$}q9+sji`S3^z5jw+)3NZ|YW-Z4gE(<0(N>2%x zMj{|msZBI-TRI1 zW0dReZvw?4trp#1UVr2ZyjTC;;)fm`dbXXx^}`w8kl`Ep+F?Ih^;-b}OutZ>RqwoW z;h}GM!#AAq9Wi`Ibl(w-f@vkrH{*-$7aqu&?op$Alp1wpgbF`o0*NnL5B#!MZ#k}e z>C7HE&R(0HX^x!q%L{t{3B7~PLafI{*nj_U#`B!vc}_2!9QeDTaV2Hezzo2Ic@PX_ z5aS@|r&L=|1og|dB8$h;=(H;4u?Wpt4FXn{VqMn2PE9CMx=56yuq?G!7@?U;Z9#Y@ z6E9hQUdP>S*X;_su`spwf#8ZO>kYhjj%$`dtzCnU0(I|Q zSsOLl4rBsDMqucd!@qX@dhRzj^%p0MW0&;FS2BlQH4eQB;_uo4;_up#@pY_RSlfdM zP&d4K^zL&;?cQ|Es6BLlN{2}58-Yr?uJ!%nKRcdwrscKUnc9A%wqN)4Gm2zfaC@uN z?@`}UVr0k%P2opz(5^GQtaJm}VX(Iz)>VAjZbieT_zdf$IW3Te#*Q7VT$6COl-v7^ za?MmI*Fx4?$~7f1l5~sGZlw}O4Y+ER#+cbj6tdDONebAK)ks&<2nup9tt?z3qK+x7 zBWxL3+GCY~o~Fz=PxL|sfL?syV0T_z3#~gpsW#e=YtnuIa%=MeaOzVWvIzjPQ@VDs@ zd|-DYT>3Fb7!{xfFxEui zqwLj`#w=gApoGh>?_{fmYKs(NaCVZ!NYS8+e8?XcCR^y(w8f+-a~r$bCoV#LMOJ26 zoQ*1~CPK#*VJ7T;RZ}3slCldn22wt zGPB9fhE>UE*p~_HHv;=fD|}Y>pVK|(_@d^dthU#w%p(Wz5SxNIdJWh7Q2ZLvRQ`bf zCkiXdr?5*4H!T{DW!nO!pHKJUW6v(Pwn0A&DDFq#u;ana?Z^0LyyRqz}^!pguCqz<~ z-zu3+tP<1HSG&5Vr~Ax~;CYEO4autm{Tqe;Xa?Riq}fJQ_#7eMZc&X&GUEt*a?qd2a?r<~mK(OdG zvD9n!KVy`pxsa7F!KE(W#FwVXgiNb{&SxD4h6?g#GG!I7OZ4?VYeSYAEx5q?Vwzw9 zSqT74$8A8Sn}Vxy5SnwtzmHTB6ShYUUHa~enTBzrVO$T4XMF+PCqieC9?kfA`6WV} zkM|9bXx*c;b1U*BNq`~GS(I5ShroPX?x(iHiaE<|Foz3je(!0L>eQUkcQQVo@dgTR;^j!JFT4MQ*7^TJfc6(p9kC0DM4|?04 z*rAy^UswRj-lAr1&C~-!Ku2B4C_bL^5El*0$=RTfi#Q!f$^qqmx)LeaO~Et;jLh7? z^R!t;d5<2Ea-VNU%9{cIlpc^=U1|nw#ZES0PHbgkrrrXXaYIqJg#e!s@6U)HKSS1_ z#|jA6MnGI~!Qsod^S#lP7gke!cUeVMiaqitYy47EYM>e`_K!&V^Q zR{AG8Ve~%&+*?Zjr7k2u)25^>z`3E63V&j&B>zYY-bTLpql_wOR$1nWb%sFSY*Pl1 zk2xy}dC;$ws;x9_RT#ngjCK^Q5~X*{^VCu{X5^@qeo+D`ZrD-UKD_Z2-drc10aIp4 ze_$8cC(hE+NW!>g+Mvq%&sCZ~dC6WDb_*J*!Slx+SW3y_o+j<`mc!Z`rFp?Rv8xyz z8i}srU1<$rC9|h3>NZO}To&g!HcZ)mBD^L@6}Rm_;@gSX)uL@txaoLJShNM*k<%Eo zOP00#CS2V~TMh9D|FcX=%Fn*MQ+J=3S^(?^OQsj&3o_sJ2T|FwNKP@h zPf~Y01^;K9&(1T38B`@%l)BxF80VZ+W;_}U5G~O#B7cdBKa*%@#+X@!9 z!-~MH@L6K*hp#=`HOO%_VOf|-2x{=5E3X$xybMY3Ua<5xb;6-%cLLvB`;;Dl%j1^9 zP(>2C;lmW+K2Yd8(%!&3l4Os({EYY5zd#hih2WIR1oZOU^1>bitP3*WFKL+oyrSwn z0eSL-CP>Rjo}gXcMYBAcE&B_Y4-zML8Z{=wQ>{r;MWiclkp>F#VVNJ(G{n`SzGpU; zT`hX%72d*be29>Ea@P zitU_-w2dTrWQ(pftD~l_s%n`X>9j1ca!cH{u!!sVaw=xLhgd7nYHMSq%V2u@c_&it^M z=T<*d3KH?*a;>AK1DE!niX?ipf+Wc2Bc?2-Dor?6D2Y3)u%*UHE*lkg3Tert7)vJR zqW=-74SUshvT|8fv4a$=g0{4q<&(k^K;Jl!N#~H)3KeN|JXp(-X(yIKWiJKqQ?QQ$ zhEe~7u9#|`fRRGJ8aW30#aQM%{3x?ub!$gh9x=uYFpfw+-rkIssrG26k_d zjp^RRFQ+V+S{#`g9)i$hZM&tfWZJ$xwx2_q3;~TZ( zdhIyOQLO{nrlHR+Z#wL)4POfgU~y{2)>M0a1KFG4^f*9h_lk|h)dwzTTBeMaDZOqg zTidj9;dhVxZ6qNgMInGd_|Vt6;pA|xbMx4}eM64rp$Nzyx+b>Oj%i3~0mO1mwhx-dnAU8P6}1RVnaF_}!&nxm zmY<3FofVb|yj8Ev=yHT%8@}&=JrJK~KkAE&g%H!XWU?*t0vns2CKG8dOBp0KP$c#| zdj~XNtSr9{m~4o!#q{)eG9gbxLuvIu=9(__*Hbm$){1STh}!C`ymhs_oL|%c7uEb| zFcmfKNP`1yBx%iVM3dMW$}n+B#i{bC1h&5u*IQ<4=si5pDyZK?gVBxQl@(k^=BCoD`E2 z0q{r=Fy~nTQB$hCl<1IVp2{1D-Cz>af({wW%&h=JY3DJFczn9X2^*29#qbQ( zkGLurPadm|f}W>2ci`EY*|AJe%v=h)Fko%uW`h}SW@e0Az6mu~VVgM#5j1y50S>`u z3znmT259zx6&A$>st_5Go`ueOI69-K7HGyKNw$$4b!5nF9J)Q`*T4`Ip&af5PQG`! zZfxX~BZ+WoA-~r`mGhsUQrRBOe9v$v2!^zNKpBuaC0D^CeBrjwt05wjX{29gZo!2vw?=yiq+Iw)aV$<1O|=3pdJ{^ zHi~*c{N1MAURhI8M8-E@_y%;}K-RaDKnv-5etu&2$#&syoJ|zAx1StwlzdK!7#jUQ z8A0$2v|@3ZE}xhZ+xfKg53m(QXUSv=e8DIqj}-Vsg!E0uNKVF#m?$DqB#Ab25F|~~ zPg!?rPSIRr23LqrTjY|`6)GB!%Tg4}DG)vccSw_Fp4$m5`3MqMr)PT4?V3Lp4PR|4=!dr`wY)My>PPCht%d={w)ERrVe)n zxs`d(l<8?pb-MgxN7j8Fw*feBJFGn4y82+HFjt;ZPEM|Zg-4drMUUqN4S3&ZY z#>6`5-hPLI805hF0+6J_KBw)+Ah;y5sV%H$oKIF@9PZ zLxBvKof(_LT)BW-Wt@VG6udyec?46+_vw;2j!FhI^0@BjA3HmaTk!Z7={;ElnU{7B z-+_y$$pl3733|r7xmgq%T<)AC(bW_MWPsv+-E5OlRneb2=YW0nN$$A_0)`Pm2PHbDmholzu11CN^m}xj|G@M>J!%VYS{01oRbDy8y zI5?>voP^1$b^rQNefaF>U741PM$5%jH>_qP&-bh!-KagN*B;F7+PixGcVFUrRxIAg z=Y5%$SB#cdR^7Bm7~90VNvOYUTZiG7e!pyP`=Y&neeVA4O#7J8K9*@dZ8V==IiK}4 zJoI&J_&VTv>gzXrwdQ9oGMWdnwXN^Iv{~s2RDCTV_$>ugg{r)u!oRe_cPs8! z1~7oiAO!~y-~$+8DLI2LH|`o8JALBHg{knx6R(EPjh~vhcyHz@QX)Yv!C+;TNbV^pN(O@+BxhS43HC=Y#Sm zbmgUh_OmFx6gVj$md6~4nWLye+>B3{Kc}mIMZrD__EYda1wW_Y9tE_}FeIh?6+s68ZlXH-sQ9xv`{#z9Jw)wYduXcGh1q${E`@V16bnkT?+Y}Hyu4!1k`R>4` ziyl-6dwTdQk5IK^v$7D0#pD4z11ffG+C8q|nsaR`-TT2C>r?l8KY2rMKW;QV52L9o zSPZ^)Ao4q}vgn(2ETPkNaBVp4`QSzDB5*+)R0zzd^uU*oI?PL;Sg^bn0!!54d{mq3 zitRq4(62Q#qp}wjHLgROLTS+Ja2-kyuY2yHLb$vyv7hpws?t@rzIRi=&;7FxratTa z)f>j}1$JK^G!3{$3K`<^0aD@Tvr+a_9!%S6Tmz4H)T|!6lh}0O8bc6hT65ibYtv14 z9-*dj_09D6^~OPC=Yh>idR8S=)vWfe9ZEaaju|z3jLN;6UV4s(S%ZT@SNEp7(sc

    (=K#>Cl^x8g<7uT`WSeP@(M)OWxp$LkZT<8;nC%Z4 zmBX7ZyxSB?gJUnb8rH_rd(oWeC!G)WJh<_zKE3O-(FV&sUX=$Y?ai*9H4FxR(r4GN z+?!yR<-w6oSIvFbrhuOZy`K$#?)tmq#t5R~zC1W-^SJg?ldZwQ=Ui0}Zf*+r`TQ*V zd1}C?E=}0+;IUi<^lMnVIHzDdgRQEJ6EP0JxC~<)jCT>20mtL2Jnol4KJa`~6k|&S z87yCO^q9*c+qlK{Qqdxfuiui95-KkCX&}bA@Cl*3(U?2b^3McSaLWVV{l#_?lii$s zd`Rh_D<*P^bhV3uE(&%d$hpG!NN$Yj+__SpI4=t3lB3E!?}=Ly4~GpX9Ja8-|4iBZ z7Ya^LutL!s@Vn!jn}H3+`iAK3K?)8b_`TB6Od%DL(E*z6ep{|7;hV4FnsUVhq{753@domnBMm!6w;FV*k=f6(Nla=%MZCD`_F z+bWEf_kdnCi1TgtW`)gG2^PO4SoNea;qd%x3VvIR;n^CO#anqb-L!3jHev68F6`QD ztFQ$i^uLmx*V_k-MzAbAxDQ5-pYovQfKANSHE%lTx2tE}eZNWXea`3_VNV{rs#XrI zx>n`2lkY~;^=b89i{1c#`##;D%Kgwi1c5V>@va$EOZEK9eXHHwiW3j3ip*P&+fUEm!U; zL4Z{jdC&q`L=Ra&ShT6qWLpF60)EUxAM#X?1{YBY7!6P)XwVlL_M*W)_4obf;AvY< zQgnCG(dg66|M=#Ae*fQh=bu=ee++Fd!iioAM|2hKI`G`H!hC*kdrx?PjNB& z>q_xySIouJvpeNZdt#onH|AyUo|G@`kNML=Oh^Y}fpk->DIJUj)1g=h`Ci$VYEHMr zTGFktR`%{sh0~E(B;6KkWA8$$J>3!ONO#6M(_OJHo}1+4z;F0iw~JG_OY7{$;jQJ; zdizao`k3dqPw{JB)o-y4b#+_UTz8|38{y>OyPO zMxWx>yjYzu>O_=H)pb5bfluvXTx|0LIkbU8`$ITvc_4=laOhOFJg^O0AIPB#9J(LE zL3|*Gb>Oi6A-&l4Kn@$gVdFzMY-b!=KHF41_iQFMqyCnM)ZZcVFL6Cvzoof3-@_N( z$4{K>aTNoyWJrmWr0YfRL{dq~Jw9Zqvqeur(v6~LFqr^7o5ZtsG&_@0ir$yiWJdj# z)*|Zr(uy&ak&7*w^3$xM8*xL@CKUrY{!@x1E1F*HQZrgwN+qu;aY>cqm+^>?Dn0I^ zFg|N2dU9g6*mgFPkWv@5jFCxXQbU@S(Tajo(qHrrT~<`1=zr1tO0n~_Ize0wG(}3i zsOU2pRac6F^W+&szlxzDRlYEBPSJH~QYnT{W>i&4P@R*hjIPK{wr6m^egGirKEB>lgd(0`thyH{i)=5|I93ALfs$Tx36DM8cN@cl$b`h^?o#| zKW?>YW|p;`5fOa#tswKxPs!!-3MGz+z(v~UPt%XK17%o^;ZaPiC#fclqHjXWTvODl zv1>*-y6%=heqJ$pFGIGP{bNS2~4;g zVaUlIr1_O5C5RkvWlp&a%MDc5E9XwQ%g?g6!54fD(wdZz9F#*7p#^S&mz&>hi8afi zSjz%;m5;SzRkUcGXt<<$IBs-G5yzFuq^c&>Nij1aN~(Bjbo8QV?UHB{TN}f);q(FX zB^nha!_boBSwk5Z5Y2sMW?_{bw-}hoy`mDGjEZAp;n|x+saX#n{KdLF- zJxgyle;R8zAe+fHI)O46hRzM+d(lBpC%LX@&bhIT79d1}^f4r*UkG((X^ zBg5KhH4r<86{#5!Q?fWCLSt+uH5lNE0qRexvT`*#Wu#LWnO+*HjEWvlh{lxDp>#%5 zMCED*Eu>wHrs|@s=m|^*nwM0?u@{F=icjxwiX5bVx^x zszl2(g_DKmVh;(yUJ)WctMrI7Qc}~S;!BD%K?9mHF))T1vv`U2p~8*;QG-Cm>b1Vp zXHFrOE=gor!5YP^G+b0PadE6d9ir4}HZ3i-U1zKVNwi8d=m2dPYu%zV(@ukFH|~q> zW1A8E5X&84oGpfpx>2>L?6y6qOE`~6@)rG8_lrJrUlc=?y<=sxJt(O45P2Nrt{Vic z9PV+k_o6>OBWXApwO(WteVSrqHT8VLJ`}x374S>d?%n|X75^b;*ttlohJVWyImooG z>M}fM5LfG(a~U=)M@lv5)HWORZR=XDsAZ>d+#C*?xf&SDbLtaot7+H=7#PmE=DeS| zs#{PEGkI>#tIw^8v)gE`Xd_<@;cB_AiKC~Aqx(nT=&j=Dc`!$HbWN>v&+*@{cXRIV zRnI%;sjVmbuKVV=OU}v}UaKZ5cBd%om= zRiYCmeAaWTK}WrH)hcK2@Wg8xFaW!(x@53=RNvu^Zkr3o8IJNt>-dth7UfWFpQ>tY zDswt@=;X!)>JcSYimN34yX*iPwNJwW>MiM$gRi=Jz{pnOnnUqo%rm4UOI7 zxTcswGg7U%P&$oAPgBvOE2)V_QqvTUO*BUF1Ue1{iB7Mgmz`b&-eHCC(dYxgBczGPLDZXv>nZ{Q3=lK6I!MI+SDg*LK!wxMMN-`)yC(^ncNv z+x9|!+Y5zlFWhmvnp^I1AOQOyJ}%r{;{1V=d?m}*etY$%FW-N((0?=^I#viB%Y}|T zO8#5Fd+lZ_fACD<;F)~rY$0?u$8M)-X!UC=m-C^g3ZbWRp{J@?-zWX88*k)8Ckmkx zxzLGH3)j`X(6qX7>qm#tjey9=duJ8~7k90;wl7}!#m^Rgwi@2BB>l2=vFW?jU~3_` zY1wxx_*gFZ*vi1o$lo7bIeNQoXKvR}zHPYBHk=C$uLe7p_+K1ZIKt9T=Gz7fZG*Yc z;MYRGsKRT1^8O#eq1z{*B4BZyOzmIHR9{ig#xqWBz!nuNQE@$6NY3d1UTWHQn z$yF1E&@6{{I6ULX)s`DkHlK`PX|#@to^gOnwtQ$yOiB6_ zwnVeF*b+)A6^~90bO z`E&E<-afb5+>!Ipo%eLCI*D!FIS<`=Pj@NIJ+W_f-R4s39`AX+#8prq7wKA5mR?%C zR0wY?`B{#@wRJCES@tZyymIiyu9d@uU55(dGdB->?)^OR#s1Hy{-w3>?8RL7#X{tT zQh?QHs^Su4X(6tA)6&rL{-x&&UAs%oEUkrW>#`aV=9*ec5tdrnp8DrkcrM&Af6D$b zm0TLF1b&^%mcn>`C#@!`o-Z0X5VZ2fp*immLk6j~S&pjvvA02EZ8 z;=7OXO1VKL*f_UFdG#|D*;iefsmQfyjTG2cx#e9?tObf}D^p~{I3vPXRkk68tQ)|W zjwB^aDCrrs7=#=)vN{AHj66=ZHiV(jhKbO@!3K4>$IZZ{nMc6VJbU`^bRTHh^}hiv z`5ysV*1?(Y1ugkCLCfW}L99oCZENEAXwb3(h6B9Q*=t?Z&{=Oa==ilR*;@yM1Urx8 z?hEaG1|93x1(*+E_9=-vcGbe2HAB=o$hfvq`koNgSFfJTamys&>#kZwi2*pj3E;GT z6gPJi0i0_a&Fu(_jI02ML8*q-B?&!yQqkCc>HiG&1Ovw( z3HCICHMiS0FHQe;f4;rH(B5C-_~ujm?XEq!p5c7gNTF*a7asY8k85ss(At~7J9#sh zKQLH0FqjVw6+%NfcCQ5*RYIUj$n@q7pezfeeIO%mGy!yW?q*nLvv+febBON|K#iYj30&9uQh=VCs*p^O zl0sF0rpKfrYDz<5!g%4Acri5x07gh)G~ z7q)6c{HyDqxJ`UdCKY%AnX^PYgO|E3~a?zlZ9H9<<8$CR4=s8W`i8p&m*2~>zi z5=a`6f5UH`Xxu=ek;ow*iNyFo7tNcfBz|7GeQez?m4-$ju^k;*`E9Y0UR*2WODqn z13Qk}K^1iY6l0Z967a5?pM)=j1tpmu6EA4JVsgSp9$DsVAyhgxmdK>XldAIEu$0mj z1bQI6Dw~D_onj^i$d@rNRt{^5!nH0l5v(|HSW;)L@DAWy$q;8VSxwY4iD|_UuV_hw z+&au^Fs){;AYy~cfVZ4M@P;u3tPRHwPI75afbhVWe0xfIm%~JtTNVAXAz(nz5obOLi04Cn!Dz+JQcS`UrT+ z$ZW*u<56*xbO{zWM;b+P5>W{#j<2aEkwl6^v)Qp2EGme&g3C#n7~gji2gIa7MOj=8 zi-f~t6(e0#(lmmY9_m5;Vo;T}hNA}9JJP3aq#L{lH7CxD4^jI*7;^$3_ZA z$kS+dO$p{OCyQr=f47;oy<_Ek0=?GB!wcW8j|;S#rn#j9%UvrSc_CU5qB$XYTWE38 zH{S^6g~J8ma85W}nZ9u)nHLTfghM&|W+!uxYk0V)siBIqo!ZOHYRte^HlZD(j2g9v zPDXY-x~aiG$6HzLndeHLEp)mQIR;nZLD(AAC9hqGl{87MDn-p}j2D)WQ}3Lk zc-?ZmsqCTXd=^m(w;Y^s|$fN_jSO@o(WGy{HPysp#su;EG{&_;zHq4bK*jq zG%74z!kCg0hdsp37$=~U;ea*ZjoRS4L1jWhz=atzHvp*clQ+l4%7PWgK8~#B`n0`qJUcE9+%inuoOBM**fGwo&%3TDGTI%l~rl=O@-D`r)M z_UY)}sC5YU4OxfqfGzC-i|F)K=@_#HvWGX_6y&QoPvLF!VEP@I2a@d3j@5>2EsoGC z;pN8&Yn$We!QDfG2A%bWi{BgaP)T9=B4ppPJb}HFtRXmJF;x9%W$DYiMrq9;8ARAz#C4 zsC{vCY1guMIlCMxZ0IX=MsIj-ynJ*2=kA+_{yARQJM_7c3!S;=cC|H?{8TkW!4Zs8 z3&lpXI_%1f%TL=K9gPAbOudh~g8lRu{#1!ybc|hh$rM;t*UV6Vs9J7q12UxJD93QJ z1%Dk-&M-QGIRgCv*9d9BKT^;?W)K`tLVd^@lNq3GCWH_zZvFFywZ&nLCD2Oh3ZZa0 z1DsDLN|YkqN=qUjJ*_~wv%fP7wS~a$;~Gi;Ej}(zWHo%r)NKg#^uolJkO&Nqp1eqU zoApIF3lJX;RScF(OL|_(P#Ae1qU)%Mu1A8518D$&|p53)^yR1Zu#|ABDr_|J@wXrcjvHuKpzYT5|I|57!#sG#{X!Rjxf( zeXnwRa*gg)?y20P++T4$xkmRYcQDuJUge(2-TyB6grEzvX_0w9CbhYH;l%sTFJ51~ z{K56*SM%L{h3>w5C|U?b(XWmzizhyKKDYJ2(q9+09=P#pe(Q6EtdDf%JCu5lNSO_ld+|}&EL?vyHvQC^ zda`iv4yE2BQf>{EQy--@i(vEMPVLO`-Fd#dz;~BiK|WC8>d9jE4yE2BLTy=BUzmxF F{{i9XMHK)5 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_headers.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_headers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad2128451e7009cceeefcfcd446d884788a8096a GIT binary patch literal 9111 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_readers.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_readers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f81ddb5e84ef69fd529a009622caac9b525e58f5 GIT binary patch literal 10788 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 Zq>*o7a*ljknc`8MfIO|$NR#0Ce*=vCc`*P0 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_receivebuffer.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_receivebuffer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bfb3416b3c84a02082b6fa85686a322e7324e6a GIT binary patch literal 5147 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_state.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_state.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bf4d5e1242c4c6e8a17e0274cd20ffbd250ef0b GIT binary patch literal 9783 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 HhNu4r&`#eg literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_util.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_util.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24760ea779fcbfd8b1a9d5521b39d74d41f2cdd0 GIT binary patch literal 5368 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_version.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_version.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcc7d205181dfa3636fb71145eb2a500f94043d7 GIT binary patch literal 205 zcmZ3^%ge<81aZ$^r>|pTV0aATzyKqZ@foCKIztLW6hjJQFoPyj6`O&cp^2V>pC;oi z?)dn!)S}|d{Ji-1l?`5{^GF7%}*)KNwq6t1DXtSQLzA! W_`uA_$oN5lfnU6V8w873fPw(;8aCSi literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/__pycache__/_writers.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/__pycache__/_writers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d2a483ee11587c64c63c19cd227897300fa81aa GIT binary patch literal 7305 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/_abnf.py b/venv/lib/python3.11/site-packages/h11/_abnf.py new file mode 100644 index 0000000..933587f --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_abnf.py @@ -0,0 +1,132 @@ +# We use native strings for all the re patterns, to take advantage of string +# formatting, and then convert to bytestrings when compiling the final re +# objects. + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#whitespace +# OWS = *( SP / HTAB ) +# ; optional whitespace +OWS = r"[ \t]*" + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.token.separators +# token = 1*tchar +# +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" +# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" +# / DIGIT / ALPHA +# ; any VCHAR, except delimiters +token = r"[-!#$%&'*+.^_`|~0-9a-zA-Z]+" + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#header.fields +# field-name = token +field_name = token + +# The standard says: +# +# field-value = *( field-content / obs-fold ) +# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] +# field-vchar = VCHAR / obs-text +# obs-fold = CRLF 1*( SP / HTAB ) +# ; obsolete line folding +# ; see Section 3.2.4 +# +# https://tools.ietf.org/html/rfc5234#appendix-B.1 +# +# VCHAR = %x21-7E +# ; visible (printing) characters +# +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#rule.quoted-string +# obs-text = %x80-FF +# +# However, the standard definition of field-content is WRONG! It disallows +# fields containing a single visible character surrounded by whitespace, +# e.g. "foo a bar". +# +# See: https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 +# +# So our definition of field_content attempts to fix it up... +# +# Also, we allow lots of control characters, because apparently people assume +# that they're legal in practice (e.g., google analytics makes cookies with +# \x01 in them!): +# https://github.com/python-hyper/h11/issues/57 +# We still don't allow NUL or whitespace, because those are often treated as +# meta-characters and letting them through can lead to nasty issues like SSRF. +vchar = r"[\x21-\x7e]" +vchar_or_obs_text = r"[^\x00\s]" +field_vchar = vchar_or_obs_text +field_content = r"{field_vchar}+(?:[ \t]+{field_vchar}+)*".format(**globals()) + +# We handle obs-fold at a different level, and our fixed-up field_content +# already grows to swallow the whole value, so ? instead of * +field_value = r"({field_content})?".format(**globals()) + +# header-field = field-name ":" OWS field-value OWS +header_field = ( + r"(?P{field_name})" + r":" + r"{OWS}" + r"(?P{field_value})" + r"{OWS}".format(**globals()) +) + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#request.line +# +# request-line = method SP request-target SP HTTP-version CRLF +# method = token +# HTTP-version = HTTP-name "/" DIGIT "." DIGIT +# HTTP-name = %x48.54.54.50 ; "HTTP", case-sensitive +# +# request-target is complicated (see RFC 7230 sec 5.3) -- could be path, full +# URL, host+port (for connect), or even "*", but in any case we are guaranteed +# that it contists of the visible printing characters. +method = token +request_target = r"{vchar}+".format(**globals()) +http_version = r"HTTP/(?P[0-9]\.[0-9])" +request_line = ( + r"(?P{method})" + r" " + r"(?P{request_target})" + r" " + r"{http_version}".format(**globals()) +) + +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#status.line +# +# status-line = HTTP-version SP status-code SP reason-phrase CRLF +# status-code = 3DIGIT +# reason-phrase = *( HTAB / SP / VCHAR / obs-text ) +status_code = r"[0-9]{3}" +reason_phrase = r"([ \t]|{vchar_or_obs_text})*".format(**globals()) +status_line = ( + r"{http_version}" + r" " + r"(?P{status_code})" + # However, there are apparently a few too many servers out there that just + # leave out the reason phrase: + # https://github.com/scrapy/scrapy/issues/345#issuecomment-281756036 + # https://github.com/seanmonstar/httparse/issues/29 + # so make it optional. ?: is a non-capturing group. + r"(?: (?P{reason_phrase}))?".format(**globals()) +) + +HEXDIG = r"[0-9A-Fa-f]" +# Actually +# +# chunk-size = 1*HEXDIG +# +# but we impose an upper-limit to avoid ridiculosity. len(str(2**64)) == 20 +chunk_size = r"({HEXDIG}){{1,20}}".format(**globals()) +# Actually +# +# chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) +# +# but we aren't parsing the things so we don't really care. +chunk_ext = r";.*" +chunk_header = ( + r"(?P{chunk_size})" + r"(?P{chunk_ext})?" + r"{OWS}\r\n".format( + **globals() + ) # Even though the specification does not allow for extra whitespaces, + # we are lenient with trailing whitespaces because some servers on the wild use it. +) diff --git a/venv/lib/python3.11/site-packages/h11/_connection.py b/venv/lib/python3.11/site-packages/h11/_connection.py new file mode 100644 index 0000000..d175270 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_connection.py @@ -0,0 +1,633 @@ +# This contains the main Connection class. Everything in h11 revolves around +# this. +from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Type, Union + +from ._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from ._headers import get_comma_header, has_expect_100_continue, set_comma_header +from ._readers import READERS, ReadersType +from ._receivebuffer import ReceiveBuffer +from ._state import ( + _SWITCH_CONNECT, + _SWITCH_UPGRADE, + CLIENT, + ConnectionState, + DONE, + ERROR, + MIGHT_SWITCH_PROTOCOL, + SEND_BODY, + SERVER, + SWITCHED_PROTOCOL, +) +from ._util import ( # Import the internal things we need + LocalProtocolError, + RemoteProtocolError, + Sentinel, +) +from ._writers import WRITERS, WritersType + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = ["Connection", "NEED_DATA", "PAUSED"] + + +class NEED_DATA(Sentinel, metaclass=Sentinel): + pass + + +class PAUSED(Sentinel, metaclass=Sentinel): + pass + + +# If we ever have this much buffered without it making a complete parseable +# event, we error out. The only time we really buffer is when reading the +# request/response line + headers together, so this is effectively the limit on +# the size of that. +# +# Some precedents for defaults: +# - node.js: 80 * 1024 +# - tomcat: 8 * 1024 +# - IIS: 16 * 1024 +# - Apache: <8 KiB per line> +DEFAULT_MAX_INCOMPLETE_EVENT_SIZE = 16 * 1024 + +# RFC 7230's rules for connection lifecycles: +# - If either side says they want to close the connection, then the connection +# must close. +# - HTTP/1.1 defaults to keep-alive unless someone says Connection: close +# - HTTP/1.0 defaults to close unless both sides say Connection: keep-alive +# (and even this is a mess -- e.g. if you're implementing a proxy then +# sending Connection: keep-alive is forbidden). +# +# We simplify life by simply not supporting keep-alive with HTTP/1.0 peers. So +# our rule is: +# - If someone says Connection: close, we will close +# - If someone uses HTTP/1.0, we will close. +def _keep_alive(event: Union[Request, Response]) -> bool: + connection = get_comma_header(event.headers, b"connection") + if b"close" in connection: + return False + if getattr(event, "http_version", b"1.1") < b"1.1": + return False + return True + + +def _body_framing( + request_method: bytes, event: Union[Request, Response] +) -> Tuple[str, Union[Tuple[()], Tuple[int]]]: + # Called when we enter SEND_BODY to figure out framing information for + # this body. + # + # These are the only two events that can trigger a SEND_BODY state: + assert type(event) in (Request, Response) + # Returns one of: + # + # ("content-length", count) + # ("chunked", ()) + # ("http/1.0", ()) + # + # which are (lookup key, *args) for constructing body reader/writer + # objects. + # + # Reference: https://tools.ietf.org/html/rfc7230#section-3.3.3 + # + # Step 1: some responses always have an empty body, regardless of what the + # headers say. + if type(event) is Response: + if ( + event.status_code in (204, 304) + or request_method == b"HEAD" + or (request_method == b"CONNECT" and 200 <= event.status_code < 300) + ): + return ("content-length", (0,)) + # Section 3.3.3 also lists another case -- responses with status_code + # < 200. For us these are InformationalResponses, not Responses, so + # they can't get into this function in the first place. + assert event.status_code >= 200 + + # Step 2: check for Transfer-Encoding (T-E beats C-L): + transfer_encodings = get_comma_header(event.headers, b"transfer-encoding") + if transfer_encodings: + assert transfer_encodings == [b"chunked"] + return ("chunked", ()) + + # Step 3: check for Content-Length + content_lengths = get_comma_header(event.headers, b"content-length") + if content_lengths: + return ("content-length", (int(content_lengths[0]),)) + + # Step 4: no applicable headers; fallback/default depends on type + if type(event) is Request: + return ("content-length", (0,)) + else: + return ("http/1.0", ()) + + +################################################################ +# +# The main Connection class +# +################################################################ + + +class Connection: + """An object encapsulating the state of an HTTP connection. + + Args: + our_role: If you're implementing a client, pass :data:`h11.CLIENT`. If + you're implementing a server, pass :data:`h11.SERVER`. + + max_incomplete_event_size (int): + The maximum number of bytes we're willing to buffer of an + incomplete event. In practice this mostly sets a limit on the + maximum size of the request/response line + headers. If this is + exceeded, then :meth:`next_event` will raise + :exc:`RemoteProtocolError`. + + """ + + def __init__( + self, + our_role: Type[Sentinel], + max_incomplete_event_size: int = DEFAULT_MAX_INCOMPLETE_EVENT_SIZE, + ) -> None: + self._max_incomplete_event_size = max_incomplete_event_size + # State and role tracking + if our_role not in (CLIENT, SERVER): + raise ValueError("expected CLIENT or SERVER, not {!r}".format(our_role)) + self.our_role = our_role + self.their_role: Type[Sentinel] + if our_role is CLIENT: + self.their_role = SERVER + else: + self.their_role = CLIENT + self._cstate = ConnectionState() + + # Callables for converting data->events or vice-versa given the + # current state + self._writer = self._get_io_object(self.our_role, None, WRITERS) + self._reader = self._get_io_object(self.their_role, None, READERS) + + # Holds any unprocessed received data + self._receive_buffer = ReceiveBuffer() + # If this is true, then it indicates that the incoming connection was + # closed *after* the end of whatever's in self._receive_buffer: + self._receive_buffer_closed = False + + # Extra bits of state that don't fit into the state machine. + # + # These two are only used to interpret framing headers for figuring + # out how to read/write response bodies. their_http_version is also + # made available as a convenient public API. + self.their_http_version: Optional[bytes] = None + self._request_method: Optional[bytes] = None + # This is pure flow-control and doesn't at all affect the set of legal + # transitions, so no need to bother ConnectionState with it: + self.client_is_waiting_for_100_continue = False + + @property + def states(self) -> Dict[Type[Sentinel], Type[Sentinel]]: + """A dictionary like:: + + {CLIENT: , SERVER: } + + See :ref:`state-machine` for details. + + """ + return dict(self._cstate.states) + + @property + def our_state(self) -> Type[Sentinel]: + """The current state of whichever role we are playing. See + :ref:`state-machine` for details. + """ + return self._cstate.states[self.our_role] + + @property + def their_state(self) -> Type[Sentinel]: + """The current state of whichever role we are NOT playing. See + :ref:`state-machine` for details. + """ + return self._cstate.states[self.their_role] + + @property + def they_are_waiting_for_100_continue(self) -> bool: + return self.their_role is CLIENT and self.client_is_waiting_for_100_continue + + def start_next_cycle(self) -> None: + """Attempt to reset our connection state for a new request/response + cycle. + + If both client and server are in :data:`DONE` state, then resets them + both to :data:`IDLE` state in preparation for a new request/response + cycle on this same connection. Otherwise, raises a + :exc:`LocalProtocolError`. + + See :ref:`keepalive-and-pipelining`. + + """ + old_states = dict(self._cstate.states) + self._cstate.start_next_cycle() + self._request_method = None + # self.their_http_version gets left alone, since it presumably lasts + # beyond a single request/response cycle + assert not self.client_is_waiting_for_100_continue + self._respond_to_state_changes(old_states) + + def _process_error(self, role: Type[Sentinel]) -> None: + old_states = dict(self._cstate.states) + self._cstate.process_error(role) + self._respond_to_state_changes(old_states) + + def _server_switch_event(self, event: Event) -> Optional[Type[Sentinel]]: + if type(event) is InformationalResponse and event.status_code == 101: + return _SWITCH_UPGRADE + if type(event) is Response: + if ( + _SWITCH_CONNECT in self._cstate.pending_switch_proposals + and 200 <= event.status_code < 300 + ): + return _SWITCH_CONNECT + return None + + # All events go through here + def _process_event(self, role: Type[Sentinel], event: Event) -> None: + # First, pass the event through the state machine to make sure it + # succeeds. + old_states = dict(self._cstate.states) + if role is CLIENT and type(event) is Request: + if event.method == b"CONNECT": + self._cstate.process_client_switch_proposal(_SWITCH_CONNECT) + if get_comma_header(event.headers, b"upgrade"): + self._cstate.process_client_switch_proposal(_SWITCH_UPGRADE) + server_switch_event = None + if role is SERVER: + server_switch_event = self._server_switch_event(event) + self._cstate.process_event(role, type(event), server_switch_event) + + # Then perform the updates triggered by it. + + if type(event) is Request: + self._request_method = event.method + + if role is self.their_role and type(event) in ( + Request, + Response, + InformationalResponse, + ): + event = cast(Union[Request, Response, InformationalResponse], event) + self.their_http_version = event.http_version + + # Keep alive handling + # + # RFC 7230 doesn't really say what one should do if Connection: close + # shows up on a 1xx InformationalResponse. I think the idea is that + # this is not supposed to happen. In any case, if it does happen, we + # ignore it. + if type(event) in (Request, Response) and not _keep_alive( + cast(Union[Request, Response], event) + ): + self._cstate.process_keep_alive_disabled() + + # 100-continue + if type(event) is Request and has_expect_100_continue(event): + self.client_is_waiting_for_100_continue = True + if type(event) in (InformationalResponse, Response): + self.client_is_waiting_for_100_continue = False + if role is CLIENT and type(event) in (Data, EndOfMessage): + self.client_is_waiting_for_100_continue = False + + self._respond_to_state_changes(old_states, event) + + def _get_io_object( + self, + role: Type[Sentinel], + event: Optional[Event], + io_dict: Union[ReadersType, WritersType], + ) -> Optional[Callable[..., Any]]: + # event may be None; it's only used when entering SEND_BODY + state = self._cstate.states[role] + if state is SEND_BODY: + # Special case: the io_dict has a dict of reader/writer factories + # that depend on the request/response framing. + framing_type, args = _body_framing( + cast(bytes, self._request_method), cast(Union[Request, Response], event) + ) + return io_dict[SEND_BODY][framing_type](*args) # type: ignore[index] + else: + # General case: the io_dict just has the appropriate reader/writer + # for this state + return io_dict.get((role, state)) # type: ignore[return-value] + + # This must be called after any action that might have caused + # self._cstate.states to change. + def _respond_to_state_changes( + self, + old_states: Dict[Type[Sentinel], Type[Sentinel]], + event: Optional[Event] = None, + ) -> None: + # Update reader/writer + if self.our_state != old_states[self.our_role]: + self._writer = self._get_io_object(self.our_role, event, WRITERS) + if self.their_state != old_states[self.their_role]: + self._reader = self._get_io_object(self.their_role, event, READERS) + + @property + def trailing_data(self) -> Tuple[bytes, bool]: + """Data that has been received, but not yet processed, represented as + a tuple with two elements, where the first is a byte-string containing + the unprocessed data itself, and the second is a bool that is True if + the receive connection was closed. + + See :ref:`switching-protocols` for discussion of why you'd want this. + """ + return (bytes(self._receive_buffer), self._receive_buffer_closed) + + def receive_data(self, data: bytes) -> None: + """Add data to our internal receive buffer. + + This does not actually do any processing on the data, just stores + it. To trigger processing, you have to call :meth:`next_event`. + + Args: + data (:term:`bytes-like object`): + The new data that was just received. + + Special case: If *data* is an empty byte-string like ``b""``, + then this indicates that the remote side has closed the + connection (end of file). Normally this is convenient, because + standard Python APIs like :meth:`file.read` or + :meth:`socket.recv` use ``b""`` to indicate end-of-file, while + other failures to read are indicated using other mechanisms + like raising :exc:`TimeoutError`. When using such an API you + can just blindly pass through whatever you get from ``read`` + to :meth:`receive_data`, and everything will work. + + But, if you have an API where reading an empty string is a + valid non-EOF condition, then you need to be aware of this and + make sure to check for such strings and avoid passing them to + :meth:`receive_data`. + + Returns: + Nothing, but after calling this you should call :meth:`next_event` + to parse the newly received data. + + Raises: + RuntimeError: + Raised if you pass an empty *data*, indicating EOF, and then + pass a non-empty *data*, indicating more data that somehow + arrived after the EOF. + + (Calling ``receive_data(b"")`` multiple times is fine, + and equivalent to calling it once.) + + """ + if data: + if self._receive_buffer_closed: + raise RuntimeError("received close, then received more data?") + self._receive_buffer += data + else: + self._receive_buffer_closed = True + + def _extract_next_receive_event( + self, + ) -> Union[Event, Type[NEED_DATA], Type[PAUSED]]: + state = self.their_state + # We don't pause immediately when they enter DONE, because even in + # DONE state we can still process a ConnectionClosed() event. But + # if we have data in our buffer, then we definitely aren't getting + # a ConnectionClosed() immediately and we need to pause. + if state is DONE and self._receive_buffer: + return PAUSED + if state is MIGHT_SWITCH_PROTOCOL or state is SWITCHED_PROTOCOL: + return PAUSED + assert self._reader is not None + event = self._reader(self._receive_buffer) + if event is None: + if not self._receive_buffer and self._receive_buffer_closed: + # In some unusual cases (basically just HTTP/1.0 bodies), EOF + # triggers an actual protocol event; in that case, we want to + # return that event, and then the state will change and we'll + # get called again to generate the actual ConnectionClosed(). + if hasattr(self._reader, "read_eof"): + event = self._reader.read_eof() # type: ignore[attr-defined] + else: + event = ConnectionClosed() + if event is None: + event = NEED_DATA + return event # type: ignore[no-any-return] + + def next_event(self) -> Union[Event, Type[NEED_DATA], Type[PAUSED]]: + """Parse the next event out of our receive buffer, update our internal + state, and return it. + + This is a mutating operation -- think of it like calling :func:`next` + on an iterator. + + Returns: + : One of three things: + + 1) An event object -- see :ref:`events`. + + 2) The special constant :data:`NEED_DATA`, which indicates that + you need to read more data from your socket and pass it to + :meth:`receive_data` before this method will be able to return + any more events. + + 3) The special constant :data:`PAUSED`, which indicates that we + are not in a state where we can process incoming data (usually + because the peer has finished their part of the current + request/response cycle, and you have not yet called + :meth:`start_next_cycle`). See :ref:`flow-control` for details. + + Raises: + RemoteProtocolError: + The peer has misbehaved. You should close the connection + (possibly after sending some kind of 4xx response). + + Once this method returns :class:`ConnectionClosed` once, then all + subsequent calls will also return :class:`ConnectionClosed`. + + If this method raises any exception besides :exc:`RemoteProtocolError` + then that's a bug -- if it happens please file a bug report! + + If this method raises any exception then it also sets + :attr:`Connection.their_state` to :data:`ERROR` -- see + :ref:`error-handling` for discussion. + + """ + + if self.their_state is ERROR: + raise RemoteProtocolError("Can't receive data when peer state is ERROR") + try: + event = self._extract_next_receive_event() + if event not in [NEED_DATA, PAUSED]: + self._process_event(self.their_role, cast(Event, event)) + if event is NEED_DATA: + if len(self._receive_buffer) > self._max_incomplete_event_size: + # 431 is "Request header fields too large" which is pretty + # much the only situation where we can get here + raise RemoteProtocolError( + "Receive buffer too long", error_status_hint=431 + ) + if self._receive_buffer_closed: + # We're still trying to complete some event, but that's + # never going to happen because no more data is coming + raise RemoteProtocolError("peer unexpectedly closed connection") + return event + except BaseException as exc: + self._process_error(self.their_role) + if isinstance(exc, LocalProtocolError): + exc._reraise_as_remote_protocol_error() + else: + raise + + def send(self, event: Event) -> Optional[bytes]: + """Convert a high-level event into bytes that can be sent to the peer, + while updating our internal state machine. + + Args: + event: The :ref:`event ` to send. + + Returns: + If ``type(event) is ConnectionClosed``, then returns + ``None``. Otherwise, returns a :term:`bytes-like object`. + + Raises: + LocalProtocolError: + Sending this event at this time would violate our + understanding of the HTTP/1.1 protocol. + + If this method raises any exception then it also sets + :attr:`Connection.our_state` to :data:`ERROR` -- see + :ref:`error-handling` for discussion. + + """ + data_list = self.send_with_data_passthrough(event) + if data_list is None: + return None + else: + return b"".join(data_list) + + def send_with_data_passthrough(self, event: Event) -> Optional[List[bytes]]: + """Identical to :meth:`send`, except that in situations where + :meth:`send` returns a single :term:`bytes-like object`, this instead + returns a list of them -- and when sending a :class:`Data` event, this + list is guaranteed to contain the exact object you passed in as + :attr:`Data.data`. See :ref:`sendfile` for discussion. + + """ + if self.our_state is ERROR: + raise LocalProtocolError("Can't send data when our state is ERROR") + try: + if type(event) is Response: + event = self._clean_up_response_headers_for_sending(event) + # We want to call _process_event before calling the writer, + # because if someone tries to do something invalid then this will + # give a sensible error message, while our writers all just assume + # they will only receive valid events. But, _process_event might + # change self._writer. So we have to do a little dance: + writer = self._writer + self._process_event(self.our_role, event) + if type(event) is ConnectionClosed: + return None + else: + # In any situation where writer is None, process_event should + # have raised ProtocolError + assert writer is not None + data_list: List[bytes] = [] + writer(event, data_list.append) + return data_list + except: + self._process_error(self.our_role) + raise + + def send_failed(self) -> None: + """Notify the state machine that we failed to send the data it gave + us. + + This causes :attr:`Connection.our_state` to immediately become + :data:`ERROR` -- see :ref:`error-handling` for discussion. + + """ + self._process_error(self.our_role) + + # When sending a Response, we take responsibility for a few things: + # + # - Sometimes you MUST set Connection: close. We take care of those + # times. (You can also set it yourself if you want, and if you do then + # we'll respect that and close the connection at the right time. But you + # don't have to worry about that unless you want to.) + # + # - The user has to set Content-Length if they want it. Otherwise, for + # responses that have bodies (e.g. not HEAD), then we will automatically + # select the right mechanism for streaming a body of unknown length, + # which depends on depending on the peer's HTTP version. + # + # This function's *only* responsibility is making sure headers are set up + # right -- everything downstream just looks at the headers. There are no + # side channels. + def _clean_up_response_headers_for_sending(self, response: Response) -> Response: + assert type(response) is Response + + headers = response.headers + need_close = False + + # HEAD requests need some special handling: they always act like they + # have Content-Length: 0, and that's how _body_framing treats + # them. But their headers are supposed to match what we would send if + # the request was a GET. (Technically there is one deviation allowed: + # we're allowed to leave out the framing headers -- see + # https://tools.ietf.org/html/rfc7231#section-4.3.2 . But it's just as + # easy to get them right.) + method_for_choosing_headers = cast(bytes, self._request_method) + if method_for_choosing_headers == b"HEAD": + method_for_choosing_headers = b"GET" + framing_type, _ = _body_framing(method_for_choosing_headers, response) + if framing_type in ("chunked", "http/1.0"): + # This response has a body of unknown length. + # If our peer is HTTP/1.1, we use Transfer-Encoding: chunked + # If our peer is HTTP/1.0, we use no framing headers, and close the + # connection afterwards. + # + # Make sure to clear Content-Length (in principle user could have + # set both and then we ignored Content-Length b/c + # Transfer-Encoding overwrote it -- this would be naughty of them, + # but the HTTP spec says that if our peer does this then we have + # to fix it instead of erroring out, so we'll accord the user the + # same respect). + headers = set_comma_header(headers, b"content-length", []) + if self.their_http_version is None or self.their_http_version < b"1.1": + # Either we never got a valid request and are sending back an + # error (their_http_version is None), so we assume the worst; + # or else we did get a valid HTTP/1.0 request, so we know that + # they don't understand chunked encoding. + headers = set_comma_header(headers, b"transfer-encoding", []) + # This is actually redundant ATM, since currently we + # unconditionally disable keep-alive when talking to HTTP/1.0 + # peers. But let's be defensive just in case we add + # Connection: keep-alive support later: + if self._request_method != b"HEAD": + need_close = True + else: + headers = set_comma_header(headers, b"transfer-encoding", [b"chunked"]) + + if not self._cstate.keep_alive or need_close: + # Make sure Connection: close is set + connection = set(get_comma_header(headers, b"connection")) + connection.discard(b"keep-alive") + connection.add(b"close") + headers = set_comma_header(headers, b"connection", sorted(connection)) + + return Response( + headers=headers, + status_code=response.status_code, + http_version=response.http_version, + reason=response.reason, + ) diff --git a/venv/lib/python3.11/site-packages/h11/_events.py b/venv/lib/python3.11/site-packages/h11/_events.py new file mode 100644 index 0000000..075bf8a --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_events.py @@ -0,0 +1,369 @@ +# High level events that make up HTTP/1.1 conversations. Loosely inspired by +# the corresponding events in hyper-h2: +# +# http://python-hyper.org/h2/en/stable/api.html#events +# +# Don't subclass these. Stuff will break. + +import re +from abc import ABC +from dataclasses import dataclass, field +from typing import Any, cast, Dict, List, Tuple, Union + +from ._abnf import method, request_target +from ._headers import Headers, normalize_and_validate +from ._util import bytesify, LocalProtocolError, validate + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = [ + "Event", + "Request", + "InformationalResponse", + "Response", + "Data", + "EndOfMessage", + "ConnectionClosed", +] + +method_re = re.compile(method.encode("ascii")) +request_target_re = re.compile(request_target.encode("ascii")) + + +class Event(ABC): + """ + Base class for h11 events. + """ + + __slots__ = () + + +@dataclass(init=False, frozen=True) +class Request(Event): + """The beginning of an HTTP request. + + Fields: + + .. attribute:: method + + An HTTP method, e.g. ``b"GET"`` or ``b"POST"``. Always a byte + string. :term:`Bytes-like objects ` and native + strings containing only ascii characters will be automatically + converted to byte strings. + + .. attribute:: target + + The target of an HTTP request, e.g. ``b"/index.html"``, or one of the + more exotic formats described in `RFC 7320, section 5.3 + `_. Always a byte + string. :term:`Bytes-like objects ` and native + strings containing only ascii characters will be automatically + converted to byte strings. + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + """ + + __slots__ = ("method", "headers", "target", "http_version") + + method: bytes + headers: Headers + target: bytes + http_version: bytes + + def __init__( + self, + *, + method: Union[bytes, str], + headers: Union[Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]]], + target: Union[bytes, str], + http_version: Union[bytes, str] = b"1.1", + _parsed: bool = False, + ) -> None: + super().__init__() + if isinstance(headers, Headers): + object.__setattr__(self, "headers", headers) + else: + object.__setattr__( + self, "headers", normalize_and_validate(headers, _parsed=_parsed) + ) + if not _parsed: + object.__setattr__(self, "method", bytesify(method)) + object.__setattr__(self, "target", bytesify(target)) + object.__setattr__(self, "http_version", bytesify(http_version)) + else: + object.__setattr__(self, "method", method) + object.__setattr__(self, "target", target) + object.__setattr__(self, "http_version", http_version) + + # "A server MUST respond with a 400 (Bad Request) status code to any + # HTTP/1.1 request message that lacks a Host header field and to any + # request message that contains more than one Host header field or a + # Host header field with an invalid field-value." + # -- https://tools.ietf.org/html/rfc7230#section-5.4 + host_count = 0 + for name, value in self.headers: + if name == b"host": + host_count += 1 + if self.http_version == b"1.1" and host_count == 0: + raise LocalProtocolError("Missing mandatory Host: header") + if host_count > 1: + raise LocalProtocolError("Found multiple Host: headers") + + validate(method_re, self.method, "Illegal method characters") + validate(request_target_re, self.target, "Illegal target characters") + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class _ResponseBase(Event): + __slots__ = ("headers", "http_version", "reason", "status_code") + + headers: Headers + http_version: bytes + reason: bytes + status_code: int + + def __init__( + self, + *, + headers: Union[Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]]], + status_code: int, + http_version: Union[bytes, str] = b"1.1", + reason: Union[bytes, str] = b"", + _parsed: bool = False, + ) -> None: + super().__init__() + if isinstance(headers, Headers): + object.__setattr__(self, "headers", headers) + else: + object.__setattr__( + self, "headers", normalize_and_validate(headers, _parsed=_parsed) + ) + if not _parsed: + object.__setattr__(self, "reason", bytesify(reason)) + object.__setattr__(self, "http_version", bytesify(http_version)) + if not isinstance(status_code, int): + raise LocalProtocolError("status code must be integer") + # Because IntEnum objects are instances of int, but aren't + # duck-compatible (sigh), see gh-72. + object.__setattr__(self, "status_code", int(status_code)) + else: + object.__setattr__(self, "reason", reason) + object.__setattr__(self, "http_version", http_version) + object.__setattr__(self, "status_code", status_code) + + self.__post_init__() + + def __post_init__(self) -> None: + pass + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class InformationalResponse(_ResponseBase): + """An HTTP informational response. + + Fields: + + .. attribute:: status_code + + The status code of this response, as an integer. For an + :class:`InformationalResponse`, this is always in the range [100, + 200). + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for + details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + .. attribute:: reason + + The reason phrase of this response, as a byte string. For example: + ``b"OK"``, or ``b"Not Found"``. + + """ + + def __post_init__(self) -> None: + if not (100 <= self.status_code < 200): + raise LocalProtocolError( + "InformationalResponse status_code should be in range " + "[100, 200), not {}".format(self.status_code) + ) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class Response(_ResponseBase): + """The beginning of an HTTP response. + + Fields: + + .. attribute:: status_code + + The status code of this response, as an integer. For an + :class:`Response`, this is always in the range [200, + 1000). + + .. attribute:: headers + + Request headers, represented as a list of (name, value) pairs. See + :ref:`the header normalization rules ` for details. + + .. attribute:: http_version + + The HTTP protocol version, represented as a byte string like + ``b"1.1"``. See :ref:`the HTTP version normalization rules + ` for details. + + .. attribute:: reason + + The reason phrase of this response, as a byte string. For example: + ``b"OK"``, or ``b"Not Found"``. + + """ + + def __post_init__(self) -> None: + if not (200 <= self.status_code < 1000): + raise LocalProtocolError( + "Response status_code should be in range [200, 1000), not {}".format( + self.status_code + ) + ) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(init=False, frozen=True) +class Data(Event): + """Part of an HTTP message body. + + Fields: + + .. attribute:: data + + A :term:`bytes-like object` containing part of a message body. Or, if + using the ``combine=False`` argument to :meth:`Connection.send`, then + any object that your socket writing code knows what to do with, and for + which calling :func:`len` returns the number of bytes that will be + written -- see :ref:`sendfile` for details. + + .. attribute:: chunk_start + + A marker that indicates whether this data object is from the start of a + chunked transfer encoding chunk. This field is ignored when when a Data + event is provided to :meth:`Connection.send`: it is only valid on + events emitted from :meth:`Connection.next_event`. You probably + shouldn't use this attribute at all; see + :ref:`chunk-delimiters-are-bad` for details. + + .. attribute:: chunk_end + + A marker that indicates whether this data object is the last for a + given chunked transfer encoding chunk. This field is ignored when when + a Data event is provided to :meth:`Connection.send`: it is only valid + on events emitted from :meth:`Connection.next_event`. You probably + shouldn't use this attribute at all; see + :ref:`chunk-delimiters-are-bad` for details. + + """ + + __slots__ = ("data", "chunk_start", "chunk_end") + + data: bytes + chunk_start: bool + chunk_end: bool + + def __init__( + self, data: bytes, chunk_start: bool = False, chunk_end: bool = False + ) -> None: + object.__setattr__(self, "data", data) + object.__setattr__(self, "chunk_start", chunk_start) + object.__setattr__(self, "chunk_end", chunk_end) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +# XX FIXME: "A recipient MUST ignore (or consider as an error) any fields that +# are forbidden to be sent in a trailer, since processing them as if they were +# present in the header section might bypass external security filters." +# https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230.html#chunked.trailer.part +# Unfortunately, the list of forbidden fields is long and vague :-/ +@dataclass(init=False, frozen=True) +class EndOfMessage(Event): + """The end of an HTTP message. + + Fields: + + .. attribute:: headers + + Default value: ``[]`` + + Any trailing headers attached to this message, represented as a list of + (name, value) pairs. See :ref:`the header normalization rules + ` for details. + + Must be empty unless ``Transfer-Encoding: chunked`` is in use. + + """ + + __slots__ = ("headers",) + + headers: Headers + + def __init__( + self, + *, + headers: Union[ + Headers, List[Tuple[bytes, bytes]], List[Tuple[str, str]], None + ] = None, + _parsed: bool = False, + ) -> None: + super().__init__() + if headers is None: + headers = Headers([]) + elif not isinstance(headers, Headers): + headers = normalize_and_validate(headers, _parsed=_parsed) + + object.__setattr__(self, "headers", headers) + + # This is an unhashable type. + __hash__ = None # type: ignore + + +@dataclass(frozen=True) +class ConnectionClosed(Event): + """This event indicates that the sender has closed their outgoing + connection. + + Note that this does not necessarily mean that they can't *receive* further + data, because TCP connections are composed to two one-way channels which + can be closed independently. See :ref:`closing` for details. + + No fields. + """ + + pass diff --git a/venv/lib/python3.11/site-packages/h11/_headers.py b/venv/lib/python3.11/site-packages/h11/_headers.py new file mode 100644 index 0000000..b97d020 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_headers.py @@ -0,0 +1,278 @@ +import re +from typing import AnyStr, cast, List, overload, Sequence, Tuple, TYPE_CHECKING, Union + +from ._abnf import field_name, field_value +from ._util import bytesify, LocalProtocolError, validate + +if TYPE_CHECKING: + from ._events import Request + +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal # type: ignore + + +# Facts +# ----- +# +# Headers are: +# keys: case-insensitive ascii +# values: mixture of ascii and raw bytes +# +# "Historically, HTTP has allowed field content with text in the ISO-8859-1 +# charset [ISO-8859-1], supporting other charsets only through use of +# [RFC2047] encoding. In practice, most HTTP header field values use only a +# subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD +# limit their field values to US-ASCII octets. A recipient SHOULD treat other +# octets in field content (obs-text) as opaque data." +# And it deprecates all non-ascii values +# +# Leading/trailing whitespace in header names is forbidden +# +# Values get leading/trailing whitespace stripped +# +# Content-Disposition actually needs to contain unicode semantically; to +# accomplish this it has a terrifically weird way of encoding the filename +# itself as ascii (and even this still has lots of cross-browser +# incompatibilities) +# +# Order is important: +# "a proxy MUST NOT change the order of these field values when forwarding a +# message" +# (and there are several headers where the order indicates a preference) +# +# Multiple occurences of the same header: +# "A sender MUST NOT generate multiple header fields with the same field name +# in a message unless either the entire field value for that header field is +# defined as a comma-separated list [or the header is Set-Cookie which gets a +# special exception]" - RFC 7230. (cookies are in RFC 6265) +# +# So every header aside from Set-Cookie can be merged by b", ".join if it +# occurs repeatedly. But, of course, they can't necessarily be split by +# .split(b","), because quoting. +# +# Given all this mess (case insensitive, duplicates allowed, order is +# important, ...), there doesn't appear to be any standard way to handle +# headers in Python -- they're almost like dicts, but... actually just +# aren't. For now we punt and just use a super simple representation: headers +# are a list of pairs +# +# [(name1, value1), (name2, value2), ...] +# +# where all entries are bytestrings, names are lowercase and have no +# leading/trailing whitespace, and values are bytestrings with no +# leading/trailing whitespace. Searching and updating are done via naive O(n) +# methods. +# +# Maybe a dict-of-lists would be better? + +_content_length_re = re.compile(rb"[0-9]+") +_field_name_re = re.compile(field_name.encode("ascii")) +_field_value_re = re.compile(field_value.encode("ascii")) + + +class Headers(Sequence[Tuple[bytes, bytes]]): + """ + A list-like interface that allows iterating over headers as byte-pairs + of (lowercased-name, value). + + Internally we actually store the representation as three-tuples, + including both the raw original casing, in order to preserve casing + over-the-wire, and the lowercased name, for case-insensitive comparisions. + + r = Request( + method="GET", + target="/", + headers=[("Host", "example.org"), ("Connection", "keep-alive")], + http_version="1.1", + ) + assert r.headers == [ + (b"host", b"example.org"), + (b"connection", b"keep-alive") + ] + assert r.headers.raw_items() == [ + (b"Host", b"example.org"), + (b"Connection", b"keep-alive") + ] + """ + + __slots__ = "_full_items" + + def __init__(self, full_items: List[Tuple[bytes, bytes, bytes]]) -> None: + self._full_items = full_items + + def __bool__(self) -> bool: + return bool(self._full_items) + + def __eq__(self, other: object) -> bool: + return list(self) == list(other) # type: ignore + + def __len__(self) -> int: + return len(self._full_items) + + def __repr__(self) -> str: + return "" % repr(list(self)) + + def __getitem__(self, idx: int) -> Tuple[bytes, bytes]: # type: ignore[override] + _, name, value = self._full_items[idx] + return (name, value) + + def raw_items(self) -> List[Tuple[bytes, bytes]]: + return [(raw_name, value) for raw_name, _, value in self._full_items] + + +HeaderTypes = Union[ + List[Tuple[bytes, bytes]], + List[Tuple[bytes, str]], + List[Tuple[str, bytes]], + List[Tuple[str, str]], +] + + +@overload +def normalize_and_validate(headers: Headers, _parsed: Literal[True]) -> Headers: + ... + + +@overload +def normalize_and_validate(headers: HeaderTypes, _parsed: Literal[False]) -> Headers: + ... + + +@overload +def normalize_and_validate( + headers: Union[Headers, HeaderTypes], _parsed: bool = False +) -> Headers: + ... + + +def normalize_and_validate( + headers: Union[Headers, HeaderTypes], _parsed: bool = False +) -> Headers: + new_headers = [] + seen_content_length = None + saw_transfer_encoding = False + for name, value in headers: + # For headers coming out of the parser, we can safely skip some steps, + # because it always returns bytes and has already run these regexes + # over the data: + if not _parsed: + name = bytesify(name) + value = bytesify(value) + validate(_field_name_re, name, "Illegal header name {!r}", name) + validate(_field_value_re, value, "Illegal header value {!r}", value) + assert isinstance(name, bytes) + assert isinstance(value, bytes) + + raw_name = name + name = name.lower() + if name == b"content-length": + lengths = {length.strip() for length in value.split(b",")} + if len(lengths) != 1: + raise LocalProtocolError("conflicting Content-Length headers") + value = lengths.pop() + validate(_content_length_re, value, "bad Content-Length") + if seen_content_length is None: + seen_content_length = value + new_headers.append((raw_name, name, value)) + elif seen_content_length != value: + raise LocalProtocolError("conflicting Content-Length headers") + elif name == b"transfer-encoding": + # "A server that receives a request message with a transfer coding + # it does not understand SHOULD respond with 501 (Not + # Implemented)." + # https://tools.ietf.org/html/rfc7230#section-3.3.1 + if saw_transfer_encoding: + raise LocalProtocolError( + "multiple Transfer-Encoding headers", error_status_hint=501 + ) + # "All transfer-coding names are case-insensitive" + # -- https://tools.ietf.org/html/rfc7230#section-4 + value = value.lower() + if value != b"chunked": + raise LocalProtocolError( + "Only Transfer-Encoding: chunked is supported", + error_status_hint=501, + ) + saw_transfer_encoding = True + new_headers.append((raw_name, name, value)) + else: + new_headers.append((raw_name, name, value)) + return Headers(new_headers) + + +def get_comma_header(headers: Headers, name: bytes) -> List[bytes]: + # Should only be used for headers whose value is a list of + # comma-separated, case-insensitive values. + # + # The header name `name` is expected to be lower-case bytes. + # + # Connection: meets these criteria (including cast insensitivity). + # + # Content-Length: technically is just a single value (1*DIGIT), but the + # standard makes reference to implementations that do multiple values, and + # using this doesn't hurt. Ditto, case insensitivity doesn't things either + # way. + # + # Transfer-Encoding: is more complex (allows for quoted strings), so + # splitting on , is actually wrong. For example, this is legal: + # + # Transfer-Encoding: foo; options="1,2", chunked + # + # and should be parsed as + # + # foo; options="1,2" + # chunked + # + # but this naive function will parse it as + # + # foo; options="1 + # 2" + # chunked + # + # However, this is okay because the only thing we are going to do with + # any Transfer-Encoding is reject ones that aren't just "chunked", so + # both of these will be treated the same anyway. + # + # Expect: the only legal value is the literal string + # "100-continue". Splitting on commas is harmless. Case insensitive. + # + out: List[bytes] = [] + for _, found_name, found_raw_value in headers._full_items: + if found_name == name: + found_raw_value = found_raw_value.lower() + for found_split_value in found_raw_value.split(b","): + found_split_value = found_split_value.strip() + if found_split_value: + out.append(found_split_value) + return out + + +def set_comma_header(headers: Headers, name: bytes, new_values: List[bytes]) -> Headers: + # The header name `name` is expected to be lower-case bytes. + # + # Note that when we store the header we use title casing for the header + # names, in order to match the conventional HTTP header style. + # + # Simply calling `.title()` is a blunt approach, but it's correct + # here given the cases where we're using `set_comma_header`... + # + # Connection, Content-Length, Transfer-Encoding. + new_headers: List[Tuple[bytes, bytes]] = [] + for found_raw_name, found_name, found_raw_value in headers._full_items: + if found_name != name: + new_headers.append((found_raw_name, found_raw_value)) + for new_value in new_values: + new_headers.append((name.title(), new_value)) + return normalize_and_validate(new_headers) + + +def has_expect_100_continue(request: "Request") -> bool: + # https://tools.ietf.org/html/rfc7231#section-5.1.1 + # "A server that receives a 100-continue expectation in an HTTP/1.0 request + # MUST ignore that expectation." + if request.http_version < b"1.1": + return False + expect = get_comma_header(request.headers, b"expect") + return b"100-continue" in expect diff --git a/venv/lib/python3.11/site-packages/h11/_readers.py b/venv/lib/python3.11/site-packages/h11/_readers.py new file mode 100644 index 0000000..08a9574 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_readers.py @@ -0,0 +1,247 @@ +# Code to read HTTP data +# +# Strategy: each reader is a callable which takes a ReceiveBuffer object, and +# either: +# 1) consumes some of it and returns an Event +# 2) raises a LocalProtocolError (for consistency -- e.g. we call validate() +# and it might raise a LocalProtocolError, so simpler just to always use +# this) +# 3) returns None, meaning "I need more data" +# +# If they have a .read_eof attribute, then this will be called if an EOF is +# received -- but this is optional. Either way, the actual ConnectionClosed +# event will be generated afterwards. +# +# READERS is a dict describing how to pick a reader. It maps states to either: +# - a reader +# - or, for body readers, a dict of per-framing reader factories + +import re +from typing import Any, Callable, Dict, Iterable, NoReturn, Optional, Tuple, Type, Union + +from ._abnf import chunk_header, header_field, request_line, status_line +from ._events import Data, EndOfMessage, InformationalResponse, Request, Response +from ._receivebuffer import ReceiveBuffer +from ._state import ( + CLIENT, + CLOSED, + DONE, + IDLE, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, +) +from ._util import LocalProtocolError, RemoteProtocolError, Sentinel, validate + +__all__ = ["READERS"] + +header_field_re = re.compile(header_field.encode("ascii")) +obs_fold_re = re.compile(rb"[ \t]+") + + +def _obsolete_line_fold(lines: Iterable[bytes]) -> Iterable[bytes]: + it = iter(lines) + last: Optional[bytes] = None + for line in it: + match = obs_fold_re.match(line) + if match: + if last is None: + raise LocalProtocolError("continuation line at start of headers") + if not isinstance(last, bytearray): + # Cast to a mutable type, avoiding copy on append to ensure O(n) time + last = bytearray(last) + last += b" " + last += line[match.end() :] + else: + if last is not None: + yield last + last = line + if last is not None: + yield last + + +def _decode_header_lines( + lines: Iterable[bytes], +) -> Iterable[Tuple[bytes, bytes]]: + for line in _obsolete_line_fold(lines): + matches = validate(header_field_re, line, "illegal header line: {!r}", line) + yield (matches["field_name"], matches["field_value"]) + + +request_line_re = re.compile(request_line.encode("ascii")) + + +def maybe_read_from_IDLE_client(buf: ReceiveBuffer) -> Optional[Request]: + lines = buf.maybe_extract_lines() + if lines is None: + if buf.is_next_line_obviously_invalid_request_line(): + raise LocalProtocolError("illegal request line") + return None + if not lines: + raise LocalProtocolError("no request line received") + matches = validate( + request_line_re, lines[0], "illegal request line: {!r}", lines[0] + ) + return Request( + headers=list(_decode_header_lines(lines[1:])), _parsed=True, **matches + ) + + +status_line_re = re.compile(status_line.encode("ascii")) + + +def maybe_read_from_SEND_RESPONSE_server( + buf: ReceiveBuffer, +) -> Union[InformationalResponse, Response, None]: + lines = buf.maybe_extract_lines() + if lines is None: + if buf.is_next_line_obviously_invalid_request_line(): + raise LocalProtocolError("illegal request line") + return None + if not lines: + raise LocalProtocolError("no response line received") + matches = validate(status_line_re, lines[0], "illegal status line: {!r}", lines[0]) + http_version = ( + b"1.1" if matches["http_version"] is None else matches["http_version"] + ) + reason = b"" if matches["reason"] is None else matches["reason"] + status_code = int(matches["status_code"]) + class_: Union[Type[InformationalResponse], Type[Response]] = ( + InformationalResponse if status_code < 200 else Response + ) + return class_( + headers=list(_decode_header_lines(lines[1:])), + _parsed=True, + status_code=status_code, + reason=reason, + http_version=http_version, + ) + + +class ContentLengthReader: + def __init__(self, length: int) -> None: + self._length = length + self._remaining = length + + def __call__(self, buf: ReceiveBuffer) -> Union[Data, EndOfMessage, None]: + if self._remaining == 0: + return EndOfMessage() + data = buf.maybe_extract_at_most(self._remaining) + if data is None: + return None + self._remaining -= len(data) + return Data(data=data) + + def read_eof(self) -> NoReturn: + raise RemoteProtocolError( + "peer closed connection without sending complete message body " + "(received {} bytes, expected {})".format( + self._length - self._remaining, self._length + ) + ) + + +chunk_header_re = re.compile(chunk_header.encode("ascii")) + + +class ChunkedReader: + def __init__(self) -> None: + self._bytes_in_chunk = 0 + # After reading a chunk, we have to throw away the trailing \r\n; if + # this is >0 then we discard that many bytes before resuming regular + # de-chunkification. + self._bytes_to_discard = 0 + self._reading_trailer = False + + def __call__(self, buf: ReceiveBuffer) -> Union[Data, EndOfMessage, None]: + if self._reading_trailer: + lines = buf.maybe_extract_lines() + if lines is None: + return None + return EndOfMessage(headers=list(_decode_header_lines(lines))) + if self._bytes_to_discard > 0: + data = buf.maybe_extract_at_most(self._bytes_to_discard) + if data is None: + return None + self._bytes_to_discard -= len(data) + if self._bytes_to_discard > 0: + return None + # else, fall through and read some more + assert self._bytes_to_discard == 0 + if self._bytes_in_chunk == 0: + # We need to refill our chunk count + chunk_header = buf.maybe_extract_next_line() + if chunk_header is None: + return None + matches = validate( + chunk_header_re, + chunk_header, + "illegal chunk header: {!r}", + chunk_header, + ) + # XX FIXME: we discard chunk extensions. Does anyone care? + self._bytes_in_chunk = int(matches["chunk_size"], base=16) + if self._bytes_in_chunk == 0: + self._reading_trailer = True + return self(buf) + chunk_start = True + else: + chunk_start = False + assert self._bytes_in_chunk > 0 + data = buf.maybe_extract_at_most(self._bytes_in_chunk) + if data is None: + return None + self._bytes_in_chunk -= len(data) + if self._bytes_in_chunk == 0: + self._bytes_to_discard = 2 + chunk_end = True + else: + chunk_end = False + return Data(data=data, chunk_start=chunk_start, chunk_end=chunk_end) + + def read_eof(self) -> NoReturn: + raise RemoteProtocolError( + "peer closed connection without sending complete message body " + "(incomplete chunked read)" + ) + + +class Http10Reader: + def __call__(self, buf: ReceiveBuffer) -> Optional[Data]: + data = buf.maybe_extract_at_most(999999999) + if data is None: + return None + return Data(data=data) + + def read_eof(self) -> EndOfMessage: + return EndOfMessage() + + +def expect_nothing(buf: ReceiveBuffer) -> None: + if buf: + raise LocalProtocolError("Got data when expecting EOF") + return None + + +ReadersType = Dict[ + Union[Type[Sentinel], Tuple[Type[Sentinel], Type[Sentinel]]], + Union[Callable[..., Any], Dict[str, Callable[..., Any]]], +] + +READERS: ReadersType = { + (CLIENT, IDLE): maybe_read_from_IDLE_client, + (SERVER, IDLE): maybe_read_from_SEND_RESPONSE_server, + (SERVER, SEND_RESPONSE): maybe_read_from_SEND_RESPONSE_server, + (CLIENT, DONE): expect_nothing, + (CLIENT, MUST_CLOSE): expect_nothing, + (CLIENT, CLOSED): expect_nothing, + (SERVER, DONE): expect_nothing, + (SERVER, MUST_CLOSE): expect_nothing, + (SERVER, CLOSED): expect_nothing, + SEND_BODY: { + "chunked": ChunkedReader, + "content-length": ContentLengthReader, + "http/1.0": Http10Reader, + }, +} diff --git a/venv/lib/python3.11/site-packages/h11/_receivebuffer.py b/venv/lib/python3.11/site-packages/h11/_receivebuffer.py new file mode 100644 index 0000000..e5c4e08 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_receivebuffer.py @@ -0,0 +1,153 @@ +import re +import sys +from typing import List, Optional, Union + +__all__ = ["ReceiveBuffer"] + + +# Operations we want to support: +# - find next \r\n or \r\n\r\n (\n or \n\n are also acceptable), +# or wait until there is one +# - read at-most-N bytes +# Goals: +# - on average, do this fast +# - worst case, do this in O(n) where n is the number of bytes processed +# Plan: +# - store bytearray, offset, how far we've searched for a separator token +# - use the how-far-we've-searched data to avoid rescanning +# - while doing a stream of uninterrupted processing, advance offset instead +# of constantly copying +# WARNING: +# - I haven't benchmarked or profiled any of this yet. +# +# Note that starting in Python 3.4, deleting the initial n bytes from a +# bytearray is amortized O(n), thanks to some excellent work by Antoine +# Martin: +# +# https://bugs.python.org/issue19087 +# +# This means that if we only supported 3.4+, we could get rid of the code here +# involving self._start and self.compress, because it's doing exactly the same +# thing that bytearray now does internally. +# +# BUT unfortunately, we still support 2.7, and reading short segments out of a +# long buffer MUST be O(bytes read) to avoid DoS issues, so we can't actually +# delete this code. Yet: +# +# https://pythonclock.org/ +# +# (Two things to double-check first though: make sure PyPy also has the +# optimization, and benchmark to make sure it's a win, since we do have a +# slightly clever thing where we delay calling compress() until we've +# processed a whole event, which could in theory be slightly more efficient +# than the internal bytearray support.) +blank_line_regex = re.compile(b"\n\r?\n", re.MULTILINE) + + +class ReceiveBuffer: + def __init__(self) -> None: + self._data = bytearray() + self._next_line_search = 0 + self._multiple_lines_search = 0 + + def __iadd__(self, byteslike: Union[bytes, bytearray]) -> "ReceiveBuffer": + self._data += byteslike + return self + + def __bool__(self) -> bool: + return bool(len(self)) + + def __len__(self) -> int: + return len(self._data) + + # for @property unprocessed_data + def __bytes__(self) -> bytes: + return bytes(self._data) + + def _extract(self, count: int) -> bytearray: + # extracting an initial slice of the data buffer and return it + out = self._data[:count] + del self._data[:count] + + self._next_line_search = 0 + self._multiple_lines_search = 0 + + return out + + def maybe_extract_at_most(self, count: int) -> Optional[bytearray]: + """ + Extract a fixed number of bytes from the buffer. + """ + out = self._data[:count] + if not out: + return None + + return self._extract(count) + + def maybe_extract_next_line(self) -> Optional[bytearray]: + """ + Extract the first line, if it is completed in the buffer. + """ + # Only search in buffer space that we've not already looked at. + search_start_index = max(0, self._next_line_search - 1) + partial_idx = self._data.find(b"\r\n", search_start_index) + + if partial_idx == -1: + self._next_line_search = len(self._data) + return None + + # + 2 is to compensate len(b"\r\n") + idx = partial_idx + 2 + + return self._extract(idx) + + def maybe_extract_lines(self) -> Optional[List[bytearray]]: + """ + Extract everything up to the first blank line, and return a list of lines. + """ + # Handle the case where we have an immediate empty line. + if self._data[:1] == b"\n": + self._extract(1) + return [] + + if self._data[:2] == b"\r\n": + self._extract(2) + return [] + + # Only search in buffer space that we've not already looked at. + match = blank_line_regex.search(self._data, self._multiple_lines_search) + if match is None: + self._multiple_lines_search = max(0, len(self._data) - 2) + return None + + # Truncate the buffer and return it. + idx = match.span(0)[-1] + out = self._extract(idx) + lines = out.split(b"\n") + + for line in lines: + if line.endswith(b"\r"): + del line[-1] + + assert lines[-2] == lines[-1] == b"" + + del lines[-2:] + + return lines + + # In theory we should wait until `\r\n` before starting to validate + # incoming data. However it's interesting to detect (very) invalid data + # early given they might not even contain `\r\n` at all (hence only + # timeout will get rid of them). + # This is not a 100% effective detection but more of a cheap sanity check + # allowing for early abort in some useful cases. + # This is especially interesting when peer is messing up with HTTPS and + # sent us a TLS stream where we were expecting plain HTTP given all + # versions of TLS so far start handshake with a 0x16 message type code. + def is_next_line_obviously_invalid_request_line(self) -> bool: + try: + # HTTP header line must not contain non-printable characters + # and should not start with a space + return self._data[0] < 0x21 + except IndexError: + return False diff --git a/venv/lib/python3.11/site-packages/h11/_state.py b/venv/lib/python3.11/site-packages/h11/_state.py new file mode 100644 index 0000000..3593430 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_state.py @@ -0,0 +1,367 @@ +################################################################ +# The core state machine +################################################################ +# +# Rule 1: everything that affects the state machine and state transitions must +# live here in this file. As much as possible goes into the table-based +# representation, but for the bits that don't quite fit, the actual code and +# state must nonetheless live here. +# +# Rule 2: this file does not know about what role we're playing; it only knows +# about HTTP request/response cycles in the abstract. This ensures that we +# don't cheat and apply different rules to local and remote parties. +# +# +# Theory of operation +# =================== +# +# Possibly the simplest way to think about this is that we actually have 5 +# different state machines here. Yes, 5. These are: +# +# 1) The client state, with its complicated automaton (see the docs) +# 2) The server state, with its complicated automaton (see the docs) +# 3) The keep-alive state, with possible states {True, False} +# 4) The SWITCH_CONNECT state, with possible states {False, True} +# 5) The SWITCH_UPGRADE state, with possible states {False, True} +# +# For (3)-(5), the first state listed is the initial state. +# +# (1)-(3) are stored explicitly in member variables. The last +# two are stored implicitly in the pending_switch_proposals set as: +# (state of 4) == (_SWITCH_CONNECT in pending_switch_proposals) +# (state of 5) == (_SWITCH_UPGRADE in pending_switch_proposals) +# +# And each of these machines has two different kinds of transitions: +# +# a) Event-triggered +# b) State-triggered +# +# Event triggered is the obvious thing that you'd think it is: some event +# happens, and if it's the right event at the right time then a transition +# happens. But there are somewhat complicated rules for which machines can +# "see" which events. (As a rule of thumb, if a machine "sees" an event, this +# means two things: the event can affect the machine, and if the machine is +# not in a state where it expects that event then it's an error.) These rules +# are: +# +# 1) The client machine sees all h11.events objects emitted by the client. +# +# 2) The server machine sees all h11.events objects emitted by the server. +# +# It also sees the client's Request event. +# +# And sometimes, server events are annotated with a _SWITCH_* event. For +# example, we can have a (Response, _SWITCH_CONNECT) event, which is +# different from a regular Response event. +# +# 3) The keep-alive machine sees the process_keep_alive_disabled() event +# (which is derived from Request/Response events), and this event +# transitions it from True -> False, or from False -> False. There's no way +# to transition back. +# +# 4&5) The _SWITCH_* machines transition from False->True when we get a +# Request that proposes the relevant type of switch (via +# process_client_switch_proposals), and they go from True->False when we +# get a Response that has no _SWITCH_* annotation. +# +# So that's event-triggered transitions. +# +# State-triggered transitions are less standard. What they do here is couple +# the machines together. The way this works is, when certain *joint* +# configurations of states are achieved, then we automatically transition to a +# new *joint* state. So, for example, if we're ever in a joint state with +# +# client: DONE +# keep-alive: False +# +# then the client state immediately transitions to: +# +# client: MUST_CLOSE +# +# This is fundamentally different from an event-based transition, because it +# doesn't matter how we arrived at the {client: DONE, keep-alive: False} state +# -- maybe the client transitioned SEND_BODY -> DONE, or keep-alive +# transitioned True -> False. Either way, once this precondition is satisfied, +# this transition is immediately triggered. +# +# What if two conflicting state-based transitions get enabled at the same +# time? In practice there's only one case where this arises (client DONE -> +# MIGHT_SWITCH_PROTOCOL versus DONE -> MUST_CLOSE), and we resolve it by +# explicitly prioritizing the DONE -> MIGHT_SWITCH_PROTOCOL transition. +# +# Implementation +# -------------- +# +# The event-triggered transitions for the server and client machines are all +# stored explicitly in a table. Ditto for the state-triggered transitions that +# involve just the server and client state. +# +# The transitions for the other machines, and the state-triggered transitions +# that involve the other machines, are written out as explicit Python code. +# +# It'd be nice if there were some cleaner way to do all this. This isn't +# *too* terrible, but I feel like it could probably be better. +# +# WARNING +# ------- +# +# The script that generates the state machine diagrams for the docs knows how +# to read out the EVENT_TRIGGERED_TRANSITIONS and STATE_TRIGGERED_TRANSITIONS +# tables. But it can't automatically read the transitions that are written +# directly in Python code. So if you touch those, you need to also update the +# script to keep it in sync! +from typing import cast, Dict, Optional, Set, Tuple, Type, Union + +from ._events import * +from ._util import LocalProtocolError, Sentinel + +# Everything in __all__ gets re-exported as part of the h11 public API. +__all__ = [ + "CLIENT", + "SERVER", + "IDLE", + "SEND_RESPONSE", + "SEND_BODY", + "DONE", + "MUST_CLOSE", + "CLOSED", + "MIGHT_SWITCH_PROTOCOL", + "SWITCHED_PROTOCOL", + "ERROR", +] + + +class CLIENT(Sentinel, metaclass=Sentinel): + pass + + +class SERVER(Sentinel, metaclass=Sentinel): + pass + + +# States +class IDLE(Sentinel, metaclass=Sentinel): + pass + + +class SEND_RESPONSE(Sentinel, metaclass=Sentinel): + pass + + +class SEND_BODY(Sentinel, metaclass=Sentinel): + pass + + +class DONE(Sentinel, metaclass=Sentinel): + pass + + +class MUST_CLOSE(Sentinel, metaclass=Sentinel): + pass + + +class CLOSED(Sentinel, metaclass=Sentinel): + pass + + +class ERROR(Sentinel, metaclass=Sentinel): + pass + + +# Switch types +class MIGHT_SWITCH_PROTOCOL(Sentinel, metaclass=Sentinel): + pass + + +class SWITCHED_PROTOCOL(Sentinel, metaclass=Sentinel): + pass + + +class _SWITCH_UPGRADE(Sentinel, metaclass=Sentinel): + pass + + +class _SWITCH_CONNECT(Sentinel, metaclass=Sentinel): + pass + + +EventTransitionType = Dict[ + Type[Sentinel], + Dict[ + Type[Sentinel], + Dict[Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]], Type[Sentinel]], + ], +] + +EVENT_TRIGGERED_TRANSITIONS: EventTransitionType = { + CLIENT: { + IDLE: {Request: SEND_BODY, ConnectionClosed: CLOSED}, + SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, + DONE: {ConnectionClosed: CLOSED}, + MUST_CLOSE: {ConnectionClosed: CLOSED}, + CLOSED: {ConnectionClosed: CLOSED}, + MIGHT_SWITCH_PROTOCOL: {}, + SWITCHED_PROTOCOL: {}, + ERROR: {}, + }, + SERVER: { + IDLE: { + ConnectionClosed: CLOSED, + Response: SEND_BODY, + # Special case: server sees client Request events, in this form + (Request, CLIENT): SEND_RESPONSE, + }, + SEND_RESPONSE: { + InformationalResponse: SEND_RESPONSE, + Response: SEND_BODY, + (InformationalResponse, _SWITCH_UPGRADE): SWITCHED_PROTOCOL, + (Response, _SWITCH_CONNECT): SWITCHED_PROTOCOL, + }, + SEND_BODY: {Data: SEND_BODY, EndOfMessage: DONE}, + DONE: {ConnectionClosed: CLOSED}, + MUST_CLOSE: {ConnectionClosed: CLOSED}, + CLOSED: {ConnectionClosed: CLOSED}, + SWITCHED_PROTOCOL: {}, + ERROR: {}, + }, +} + +StateTransitionType = Dict[ + Tuple[Type[Sentinel], Type[Sentinel]], Dict[Type[Sentinel], Type[Sentinel]] +] + +# NB: there are also some special-case state-triggered transitions hard-coded +# into _fire_state_triggered_transitions below. +STATE_TRIGGERED_TRANSITIONS: StateTransitionType = { + # (Client state, Server state) -> new states + # Protocol negotiation + (MIGHT_SWITCH_PROTOCOL, SWITCHED_PROTOCOL): {CLIENT: SWITCHED_PROTOCOL}, + # Socket shutdown + (CLOSED, DONE): {SERVER: MUST_CLOSE}, + (CLOSED, IDLE): {SERVER: MUST_CLOSE}, + (ERROR, DONE): {SERVER: MUST_CLOSE}, + (DONE, CLOSED): {CLIENT: MUST_CLOSE}, + (IDLE, CLOSED): {CLIENT: MUST_CLOSE}, + (DONE, ERROR): {CLIENT: MUST_CLOSE}, +} + + +class ConnectionState: + def __init__(self) -> None: + # Extra bits of state that don't quite fit into the state model. + + # If this is False then it enables the automatic DONE -> MUST_CLOSE + # transition. Don't set this directly; call .keep_alive_disabled() + self.keep_alive = True + + # This is a subset of {UPGRADE, CONNECT}, containing the proposals + # made by the client for switching protocols. + self.pending_switch_proposals: Set[Type[Sentinel]] = set() + + self.states: Dict[Type[Sentinel], Type[Sentinel]] = {CLIENT: IDLE, SERVER: IDLE} + + def process_error(self, role: Type[Sentinel]) -> None: + self.states[role] = ERROR + self._fire_state_triggered_transitions() + + def process_keep_alive_disabled(self) -> None: + self.keep_alive = False + self._fire_state_triggered_transitions() + + def process_client_switch_proposal(self, switch_event: Type[Sentinel]) -> None: + self.pending_switch_proposals.add(switch_event) + self._fire_state_triggered_transitions() + + def process_event( + self, + role: Type[Sentinel], + event_type: Type[Event], + server_switch_event: Optional[Type[Sentinel]] = None, + ) -> None: + _event_type: Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]] = event_type + if server_switch_event is not None: + assert role is SERVER + if server_switch_event not in self.pending_switch_proposals: + raise LocalProtocolError( + "Received server {} event without a pending proposal".format( + server_switch_event + ) + ) + _event_type = (event_type, server_switch_event) + if server_switch_event is None and _event_type is Response: + self.pending_switch_proposals = set() + self._fire_event_triggered_transitions(role, _event_type) + # Special case: the server state does get to see Request + # events. + if _event_type is Request: + assert role is CLIENT + self._fire_event_triggered_transitions(SERVER, (Request, CLIENT)) + self._fire_state_triggered_transitions() + + def _fire_event_triggered_transitions( + self, + role: Type[Sentinel], + event_type: Union[Type[Event], Tuple[Type[Event], Type[Sentinel]]], + ) -> None: + state = self.states[role] + try: + new_state = EVENT_TRIGGERED_TRANSITIONS[role][state][event_type] + except KeyError: + event_type = cast(Type[Event], event_type) + raise LocalProtocolError( + "can't handle event type {} when role={} and state={}".format( + event_type.__name__, role, self.states[role] + ) + ) from None + self.states[role] = new_state + + def _fire_state_triggered_transitions(self) -> None: + # We apply these rules repeatedly until converging on a fixed point + while True: + start_states = dict(self.states) + + # It could happen that both these special-case transitions are + # enabled at the same time: + # + # DONE -> MIGHT_SWITCH_PROTOCOL + # DONE -> MUST_CLOSE + # + # For example, this will always be true of a HTTP/1.0 client + # requesting CONNECT. If this happens, the protocol switch takes + # priority. From there the client will either go to + # SWITCHED_PROTOCOL, in which case it's none of our business when + # they close the connection, or else the server will deny the + # request, in which case the client will go back to DONE and then + # from there to MUST_CLOSE. + if self.pending_switch_proposals: + if self.states[CLIENT] is DONE: + self.states[CLIENT] = MIGHT_SWITCH_PROTOCOL + + if not self.pending_switch_proposals: + if self.states[CLIENT] is MIGHT_SWITCH_PROTOCOL: + self.states[CLIENT] = DONE + + if not self.keep_alive: + for role in (CLIENT, SERVER): + if self.states[role] is DONE: + self.states[role] = MUST_CLOSE + + # Tabular state-triggered transitions + joint_state = (self.states[CLIENT], self.states[SERVER]) + changes = STATE_TRIGGERED_TRANSITIONS.get(joint_state, {}) + self.states.update(changes) + + if self.states == start_states: + # Fixed point reached + return + + def start_next_cycle(self) -> None: + if self.states != {CLIENT: DONE, SERVER: DONE}: + raise LocalProtocolError( + "not in a reusable state. self.states={}".format(self.states) + ) + # Can't reach DONE/DONE with any of these active, but still, let's be + # sure. + assert self.keep_alive + assert not self.pending_switch_proposals + self.states = {CLIENT: IDLE, SERVER: IDLE} diff --git a/venv/lib/python3.11/site-packages/h11/_util.py b/venv/lib/python3.11/site-packages/h11/_util.py new file mode 100644 index 0000000..6718445 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_util.py @@ -0,0 +1,135 @@ +from typing import Any, Dict, NoReturn, Pattern, Tuple, Type, TypeVar, Union + +__all__ = [ + "ProtocolError", + "LocalProtocolError", + "RemoteProtocolError", + "validate", + "bytesify", +] + + +class ProtocolError(Exception): + """Exception indicating a violation of the HTTP/1.1 protocol. + + This as an abstract base class, with two concrete base classes: + :exc:`LocalProtocolError`, which indicates that you tried to do something + that HTTP/1.1 says is illegal, and :exc:`RemoteProtocolError`, which + indicates that the remote peer tried to do something that HTTP/1.1 says is + illegal. See :ref:`error-handling` for details. + + In addition to the normal :exc:`Exception` features, it has one attribute: + + .. attribute:: error_status_hint + + This gives a suggestion as to what status code a server might use if + this error occurred as part of a request. + + For a :exc:`RemoteProtocolError`, this is useful as a suggestion for + how you might want to respond to a misbehaving peer, if you're + implementing a server. + + For a :exc:`LocalProtocolError`, this can be taken as a suggestion for + how your peer might have responded to *you* if h11 had allowed you to + continue. + + The default is 400 Bad Request, a generic catch-all for protocol + violations. + + """ + + def __init__(self, msg: str, error_status_hint: int = 400) -> None: + if type(self) is ProtocolError: + raise TypeError("tried to directly instantiate ProtocolError") + Exception.__init__(self, msg) + self.error_status_hint = error_status_hint + + +# Strategy: there are a number of public APIs where a LocalProtocolError can +# be raised (send(), all the different event constructors, ...), and only one +# public API where RemoteProtocolError can be raised +# (receive_data()). Therefore we always raise LocalProtocolError internally, +# and then receive_data will translate this into a RemoteProtocolError. +# +# Internally: +# LocalProtocolError is the generic "ProtocolError". +# Externally: +# LocalProtocolError is for local errors and RemoteProtocolError is for +# remote errors. +class LocalProtocolError(ProtocolError): + def _reraise_as_remote_protocol_error(self) -> NoReturn: + # After catching a LocalProtocolError, use this method to re-raise it + # as a RemoteProtocolError. This method must be called from inside an + # except: block. + # + # An easy way to get an equivalent RemoteProtocolError is just to + # modify 'self' in place. + self.__class__ = RemoteProtocolError # type: ignore + # But the re-raising is somewhat non-trivial -- you might think that + # now that we've modified the in-flight exception object, that just + # doing 'raise' to re-raise it would be enough. But it turns out that + # this doesn't work, because Python tracks the exception type + # (exc_info[0]) separately from the exception object (exc_info[1]), + # and we only modified the latter. So we really do need to re-raise + # the new type explicitly. + # On py3, the traceback is part of the exception object, so our + # in-place modification preserved it and we can just re-raise: + raise self + + +class RemoteProtocolError(ProtocolError): + pass + + +def validate( + regex: Pattern[bytes], data: bytes, msg: str = "malformed data", *format_args: Any +) -> Dict[str, bytes]: + match = regex.fullmatch(data) + if not match: + if format_args: + msg = msg.format(*format_args) + raise LocalProtocolError(msg) + return match.groupdict() + + +# Sentinel values +# +# - Inherit identity-based comparison and hashing from object +# - Have a nice repr +# - Have a *bonus property*: type(sentinel) is sentinel +# +# The bonus property is useful if you want to take the return value from +# next_event() and do some sort of dispatch based on type(event). + +_T_Sentinel = TypeVar("_T_Sentinel", bound="Sentinel") + + +class Sentinel(type): + def __new__( + cls: Type[_T_Sentinel], + name: str, + bases: Tuple[type, ...], + namespace: Dict[str, Any], + **kwds: Any + ) -> _T_Sentinel: + assert bases == (Sentinel,) + v = super().__new__(cls, name, bases, namespace, **kwds) + v.__class__ = v # type: ignore + return v + + def __repr__(self) -> str: + return self.__name__ + + +# Used for methods, request targets, HTTP versions, header names, and header +# values. Accepts ascii-strings, or bytes/bytearray/memoryview/..., and always +# returns bytes. +def bytesify(s: Union[bytes, bytearray, memoryview, int, str]) -> bytes: + # Fast-path: + if type(s) is bytes: + return s + if isinstance(s, str): + s = s.encode("ascii") + if isinstance(s, int): + raise TypeError("expected bytes-like object, not int") + return bytes(s) diff --git a/venv/lib/python3.11/site-packages/h11/_version.py b/venv/lib/python3.11/site-packages/h11/_version.py new file mode 100644 index 0000000..4c89113 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_version.py @@ -0,0 +1,16 @@ +# This file must be kept very simple, because it is consumed from several +# places -- it is imported by h11/__init__.py, execfile'd by setup.py, etc. + +# We use a simple scheme: +# 1.0.0 -> 1.0.0+dev -> 1.1.0 -> 1.1.0+dev +# where the +dev versions are never released into the wild, they're just what +# we stick into the VCS in between releases. +# +# This is compatible with PEP 440: +# http://legacy.python.org/dev/peps/pep-0440/ +# via the use of the "local suffix" "+dev", which is disallowed on index +# servers and causes 1.0.0+dev to sort after plain 1.0.0, which is what we +# want. (Contrast with the special suffix 1.0.0.dev, which sorts *before* +# 1.0.0.) + +__version__ = "0.14.0" diff --git a/venv/lib/python3.11/site-packages/h11/_writers.py b/venv/lib/python3.11/site-packages/h11/_writers.py new file mode 100644 index 0000000..939cdb9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/_writers.py @@ -0,0 +1,145 @@ +# Code to read HTTP data +# +# Strategy: each writer takes an event + a write-some-bytes function, which is +# calls. +# +# WRITERS is a dict describing how to pick a reader. It maps states to either: +# - a writer +# - or, for body writers, a dict of framin-dependent writer factories + +from typing import Any, Callable, Dict, List, Tuple, Type, Union + +from ._events import Data, EndOfMessage, Event, InformationalResponse, Request, Response +from ._headers import Headers +from ._state import CLIENT, IDLE, SEND_BODY, SEND_RESPONSE, SERVER +from ._util import LocalProtocolError, Sentinel + +__all__ = ["WRITERS"] + +Writer = Callable[[bytes], Any] + + +def write_headers(headers: Headers, write: Writer) -> None: + # "Since the Host field-value is critical information for handling a + # request, a user agent SHOULD generate Host as the first header field + # following the request-line." - RFC 7230 + raw_items = headers._full_items + for raw_name, name, value in raw_items: + if name == b"host": + write(b"%s: %s\r\n" % (raw_name, value)) + for raw_name, name, value in raw_items: + if name != b"host": + write(b"%s: %s\r\n" % (raw_name, value)) + write(b"\r\n") + + +def write_request(request: Request, write: Writer) -> None: + if request.http_version != b"1.1": + raise LocalProtocolError("I only send HTTP/1.1") + write(b"%s %s HTTP/1.1\r\n" % (request.method, request.target)) + write_headers(request.headers, write) + + +# Shared between InformationalResponse and Response +def write_any_response( + response: Union[InformationalResponse, Response], write: Writer +) -> None: + if response.http_version != b"1.1": + raise LocalProtocolError("I only send HTTP/1.1") + status_bytes = str(response.status_code).encode("ascii") + # We don't bother sending ascii status messages like "OK"; they're + # optional and ignored by the protocol. (But the space after the numeric + # status code is mandatory.) + # + # XX FIXME: could at least make an effort to pull out the status message + # from stdlib's http.HTTPStatus table. Or maybe just steal their enums + # (either by import or copy/paste). We already accept them as status codes + # since they're of type IntEnum < int. + write(b"HTTP/1.1 %s %s\r\n" % (status_bytes, response.reason)) + write_headers(response.headers, write) + + +class BodyWriter: + def __call__(self, event: Event, write: Writer) -> None: + if type(event) is Data: + self.send_data(event.data, write) + elif type(event) is EndOfMessage: + self.send_eom(event.headers, write) + else: # pragma: no cover + assert False + + def send_data(self, data: bytes, write: Writer) -> None: + pass + + def send_eom(self, headers: Headers, write: Writer) -> None: + pass + + +# +# These are all careful not to do anything to 'data' except call len(data) and +# write(data). This allows us to transparently pass-through funny objects, +# like placeholder objects referring to files on disk that will be sent via +# sendfile(2). +# +class ContentLengthWriter(BodyWriter): + def __init__(self, length: int) -> None: + self._length = length + + def send_data(self, data: bytes, write: Writer) -> None: + self._length -= len(data) + if self._length < 0: + raise LocalProtocolError("Too much data for declared Content-Length") + write(data) + + def send_eom(self, headers: Headers, write: Writer) -> None: + if self._length != 0: + raise LocalProtocolError("Too little data for declared Content-Length") + if headers: + raise LocalProtocolError("Content-Length and trailers don't mix") + + +class ChunkedWriter(BodyWriter): + def send_data(self, data: bytes, write: Writer) -> None: + # if we encoded 0-length data in the naive way, it would look like an + # end-of-message. + if not data: + return + write(b"%x\r\n" % len(data)) + write(data) + write(b"\r\n") + + def send_eom(self, headers: Headers, write: Writer) -> None: + write(b"0\r\n") + write_headers(headers, write) + + +class Http10Writer(BodyWriter): + def send_data(self, data: bytes, write: Writer) -> None: + write(data) + + def send_eom(self, headers: Headers, write: Writer) -> None: + if headers: + raise LocalProtocolError("can't send trailers to HTTP/1.0 client") + # no need to close the socket ourselves, that will be taken care of by + # Connection: close machinery + + +WritersType = Dict[ + Union[Tuple[Type[Sentinel], Type[Sentinel]], Type[Sentinel]], + Union[ + Dict[str, Type[BodyWriter]], + Callable[[Union[InformationalResponse, Response], Writer], None], + Callable[[Request, Writer], None], + ], +] + +WRITERS: WritersType = { + (CLIENT, IDLE): write_request, + (SERVER, IDLE): write_any_response, + (SERVER, SEND_RESPONSE): write_any_response, + SEND_BODY: { + "chunked": ChunkedWriter, + "content-length": ContentLengthWriter, + "http/1.0": Http10Writer, + }, +} diff --git a/venv/lib/python3.11/site-packages/h11/py.typed b/venv/lib/python3.11/site-packages/h11/py.typed new file mode 100644 index 0000000..f5642f7 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/py.typed @@ -0,0 +1 @@ +Marker diff --git a/venv/lib/python3.11/site-packages/h11/tests/__init__.py b/venv/lib/python3.11/site-packages/h11/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b07c083779165ab6b8c961f0e36b72010a4f5f22 GIT binary patch literal 188 zcmZ3^%ge<81aZ$^r-SInAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnFMs{A#3KFj z@^byu-2AM})Uy1X(vr;lJpHoNyfXcq%q0DS%94!yJYzjWL;d2+l2qM-#N_P6^weVg z44_C!YH>-ietdjpUS>&ryk0@&FAkgB{FKt1RJ$Tpp!pyd6!Qa#56p~=j2{?aL=iJk F3;@zdFX#XO literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/helpers.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/helpers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac19c5d15227e008edde34290c4778043007372b GIT binary patch literal 5108 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_connection.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_connection.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ae4dd5acb368adaf64a4759dd3e8e2cb60c1437 GIT binary patch literal 68024 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 p_d0E1{~u*I0d4>Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_events.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_events.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..10410825d412295caea70f3bfb4a1138486ffa6f GIT binary patch literal 6824 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_headers.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_headers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a81f40e5807a058024cebb6586076ca5d1b045d GIT binary patch literal 9601 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 Of-S~!7>mU^-~SJL>>!^2 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_receivebuffer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7120712643387e2552f43421c4fd4ea960df5411 GIT binary patch literal 4603 zcmb^!OK%%Rcy_((*gM|DX_GW9kGfClpw>8POGzsb?~0=Gs)UFDYn|DorhbIkO+t!W zIj9F0<Q{Fe8zH8`5pS-D%^eFcIEC>A@|AxtJCl`O^GcQQuw7%pd++)~wb~{(A^ppI4tTQ$Dy(=FUX}ce`cJ|6MsUy3CptMH`d+jL zWV%)%6gyFO5`~+CuKLxW_oV-S);|!^pWKOlG8mNZDYv_JF4IGv!gbi)j-zA!Z#SE+ z2~}Yhk)f}9-=Bsr=;!DO<>aZ;s`B)iXH>;t zeHCO~l))10;$598$4s0&rKkq$&e?I*eStoKl+(bfX&Q*P6}e=^NB})Rew<4Kqc)k! ztIABJGMU$?s;G)dwL-B_o=rz6bH-o+FeZZ?3|f5LxW{NP-#~JUFm?=sM**b40_{*5 zr7R{VQq;?ioL@3^!x=7VOL;w~e*$9DW==D6rHWxXdxGdP&~xCI?(7Z{7|uwGj*xd` z{>-zTN&FV(xGGM?p)8J!{x@U$wKQo+|TXJ?WVh~ODKwLawUqC);=w592=D^B8?fH#? zWbJi!-^2a&k8hq{IeqJ`&(GHReGeyZ4c%0PYv2U#HnlH0x0XuPEEpcc)aj5q422NT-Sr=@a zwLI_@eG0S5@_;8eW#iNuKDf@1V=l0S>|MUt3hJL2+SQ*}!%wW^C#)yW+4!90L3`=& z6xCr0j6S4nHE-i%mIvE-=(=89UO47=)Xmt5AT*-kQ}2Whtc->H=JRK7x% zoZX8B^Kx#Q7H4uqFBVF$#ZdSJ5ep4H{Q?Ls2Mm+!^5( z!Cs|YTQ&zIHM42i&1cM{7enW@hk$1@yTy%sHjy>ETax)d0 zE0h%>o+{Uq)9BLpz-o=Nyv=NKfFWrpSg}SgAUa*@u z*+9~8)F1vpQi8p94u2^qG1%%iRU03&g20zYTBPvR3m?u2N2IzFg*5W<7`c?=jlQ0T&Y6li~6(lIEb@J zVhq99hzNqPf#NlOZ=g{t2%AW)@p}`ESwUz-F9^b+26||GUqoW;#v^xyQCk?@kd)2X zP(8YmXoyj@ztNA9M;e3ixN;xC@FyD@LnuBR;5fE(jwkoa(fjg2QT!9Z(0D~qg~LCb b`f2#ba}5NKKflEP{NetqLXg=f@vQv~wnou- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_state.cpython-311.pyc b/venv/lib/python3.11/site-packages/h11/tests/__pycache__/test_state.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ade9a33c9903f248787ee2c9ec80aa7a4a8a903f GIT binary patch literal 15205 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 List[Event]: + got_events = [] + while True: + event = conn.next_event() + if event in (NEED_DATA, PAUSED): + break + event = cast(Event, event) + got_events.append(event) + if type(event) is ConnectionClosed: + break + return got_events + + +def receive_and_get(conn: Connection, data: bytes) -> List[Event]: + conn.receive_data(data) + return get_all_events(conn) + + +# Merges adjacent Data events, converts payloads to bytestrings, and removes +# chunk boundaries. +def normalize_data_events(in_events: List[Event]) -> List[Event]: + out_events: List[Event] = [] + for event in in_events: + if type(event) is Data: + event = Data(data=bytes(event.data), chunk_start=False, chunk_end=False) + if out_events and type(out_events[-1]) is type(event) is Data: + out_events[-1] = Data( + data=out_events[-1].data + event.data, + chunk_start=out_events[-1].chunk_start, + chunk_end=out_events[-1].chunk_end, + ) + else: + out_events.append(event) + return out_events + + +# Given that we want to write tests that push some events through a Connection +# and check that its state updates appropriately... we might as make a habit +# of pushing them through two Connections with a fake network link in +# between. +class ConnectionPair: + def __init__(self) -> None: + self.conn = {CLIENT: Connection(CLIENT), SERVER: Connection(SERVER)} + self.other = {CLIENT: SERVER, SERVER: CLIENT} + + @property + def conns(self) -> ValuesView[Connection]: + return self.conn.values() + + # expect="match" if expect=send_events; expect=[...] to say what expected + def send( + self, + role: Type[Sentinel], + send_events: Union[List[Event], Event], + expect: Union[List[Event], Event, Literal["match"]] = "match", + ) -> bytes: + if not isinstance(send_events, list): + send_events = [send_events] + data = b"" + closed = False + for send_event in send_events: + new_data = self.conn[role].send(send_event) + if new_data is None: + closed = True + else: + data += new_data + # send uses b"" to mean b"", and None to mean closed + # receive uses b"" to mean closed, and None to mean "try again" + # so we have to translate between the two conventions + if data: + self.conn[self.other[role]].receive_data(data) + if closed: + self.conn[self.other[role]].receive_data(b"") + got_events = get_all_events(self.conn[self.other[role]]) + if expect == "match": + expect = send_events + if not isinstance(expect, list): + expect = [expect] + assert got_events == expect + return data diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_against_stdlib_http.py b/venv/lib/python3.11/site-packages/h11/tests/test_against_stdlib_http.py new file mode 100644 index 0000000..d2ee131 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_against_stdlib_http.py @@ -0,0 +1,115 @@ +import json +import os.path +import socket +import socketserver +import threading +from contextlib import closing, contextmanager +from http.server import SimpleHTTPRequestHandler +from typing import Callable, Generator +from urllib.request import urlopen + +import h11 + + +@contextmanager +def socket_server( + handler: Callable[..., socketserver.BaseRequestHandler] +) -> Generator[socketserver.TCPServer, None, None]: + httpd = socketserver.TCPServer(("127.0.0.1", 0), handler) + thread = threading.Thread( + target=httpd.serve_forever, kwargs={"poll_interval": 0.01} + ) + thread.daemon = True + try: + thread.start() + yield httpd + finally: + httpd.shutdown() + + +test_file_path = os.path.join(os.path.dirname(__file__), "data/test-file") +with open(test_file_path, "rb") as f: + test_file_data = f.read() + + +class SingleMindedRequestHandler(SimpleHTTPRequestHandler): + def translate_path(self, path: str) -> str: + return test_file_path + + +def test_h11_as_client() -> None: + with socket_server(SingleMindedRequestHandler) as httpd: + with closing(socket.create_connection(httpd.server_address)) as s: + c = h11.Connection(h11.CLIENT) + + s.sendall( + c.send( # type: ignore[arg-type] + h11.Request( + method="GET", target="/foo", headers=[("Host", "localhost")] + ) + ) + ) + s.sendall(c.send(h11.EndOfMessage())) # type: ignore[arg-type] + + data = bytearray() + while True: + event = c.next_event() + print(event) + if event is h11.NEED_DATA: + # Use a small read buffer to make things more challenging + # and exercise more paths :-) + c.receive_data(s.recv(10)) + continue + if type(event) is h11.Response: + assert event.status_code == 200 + if type(event) is h11.Data: + data += event.data + if type(event) is h11.EndOfMessage: + break + assert bytes(data) == test_file_data + + +class H11RequestHandler(socketserver.BaseRequestHandler): + def handle(self) -> None: + with closing(self.request) as s: + c = h11.Connection(h11.SERVER) + request = None + while True: + event = c.next_event() + if event is h11.NEED_DATA: + # Use a small read buffer to make things more challenging + # and exercise more paths :-) + c.receive_data(s.recv(10)) + continue + if type(event) is h11.Request: + request = event + if type(event) is h11.EndOfMessage: + break + assert request is not None + info = json.dumps( + { + "method": request.method.decode("ascii"), + "target": request.target.decode("ascii"), + "headers": { + name.decode("ascii"): value.decode("ascii") + for (name, value) in request.headers + }, + } + ) + s.sendall(c.send(h11.Response(status_code=200, headers=[]))) # type: ignore[arg-type] + s.sendall(c.send(h11.Data(data=info.encode("ascii")))) + s.sendall(c.send(h11.EndOfMessage())) + + +def test_h11_as_server() -> None: + with socket_server(H11RequestHandler) as httpd: + host, port = httpd.server_address + url = "http://{}:{}/some-path".format(host, port) + with closing(urlopen(url)) as f: + assert f.getcode() == 200 + data = f.read() + info = json.loads(data.decode("ascii")) + print(info) + assert info["method"] == "GET" + assert info["target"] == "/some-path" + assert "urllib" in info["headers"]["user-agent"] diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_connection.py b/venv/lib/python3.11/site-packages/h11/tests/test_connection.py new file mode 100644 index 0000000..73a27b9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_connection.py @@ -0,0 +1,1122 @@ +from typing import Any, cast, Dict, List, Optional, Tuple, Type + +import pytest + +from .._connection import _body_framing, _keep_alive, Connection, NEED_DATA, PAUSED +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._state import ( + CLIENT, + CLOSED, + DONE, + ERROR, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from .._util import LocalProtocolError, RemoteProtocolError, Sentinel +from .helpers import ConnectionPair, get_all_events, receive_and_get + + +def test__keep_alive() -> None: + assert _keep_alive( + Request(method="GET", target="/", headers=[("Host", "Example.com")]) + ) + assert not _keep_alive( + Request( + method="GET", + target="/", + headers=[("Host", "Example.com"), ("Connection", "close")], + ) + ) + assert not _keep_alive( + Request( + method="GET", + target="/", + headers=[("Host", "Example.com"), ("Connection", "a, b, cLOse, foo")], + ) + ) + assert not _keep_alive( + Request(method="GET", target="/", headers=[], http_version="1.0") # type: ignore[arg-type] + ) + + assert _keep_alive(Response(status_code=200, headers=[])) # type: ignore[arg-type] + assert not _keep_alive(Response(status_code=200, headers=[("Connection", "close")])) + assert not _keep_alive( + Response(status_code=200, headers=[("Connection", "a, b, cLOse, foo")]) + ) + assert not _keep_alive(Response(status_code=200, headers=[], http_version="1.0")) # type: ignore[arg-type] + + +def test__body_framing() -> None: + def headers(cl: Optional[int], te: bool) -> List[Tuple[str, str]]: + headers = [] + if cl is not None: + headers.append(("Content-Length", str(cl))) + if te: + headers.append(("Transfer-Encoding", "chunked")) + return headers + + def resp( + status_code: int = 200, cl: Optional[int] = None, te: bool = False + ) -> Response: + return Response(status_code=status_code, headers=headers(cl, te)) + + def req(cl: Optional[int] = None, te: bool = False) -> Request: + h = headers(cl, te) + h += [("Host", "example.com")] + return Request(method="GET", target="/", headers=h) + + # Special cases where the headers are ignored: + for kwargs in [{}, {"cl": 100}, {"te": True}, {"cl": 100, "te": True}]: + kwargs = cast(Dict[str, Any], kwargs) + for meth, r in [ + (b"HEAD", resp(**kwargs)), + (b"GET", resp(status_code=204, **kwargs)), + (b"GET", resp(status_code=304, **kwargs)), + ]: + assert _body_framing(meth, r) == ("content-length", (0,)) + + # Transfer-encoding + for kwargs in [{"te": True}, {"cl": 100, "te": True}]: + kwargs = cast(Dict[str, Any], kwargs) + for meth, r in [(None, req(**kwargs)), (b"GET", resp(**kwargs))]: # type: ignore + assert _body_framing(meth, r) == ("chunked", ()) + + # Content-Length + for meth, r in [(None, req(cl=100)), (b"GET", resp(cl=100))]: # type: ignore + assert _body_framing(meth, r) == ("content-length", (100,)) + + # No headers + assert _body_framing(None, req()) == ("content-length", (0,)) # type: ignore + assert _body_framing(b"GET", resp()) == ("http/1.0", ()) + + +def test_Connection_basics_and_content_length() -> None: + with pytest.raises(ValueError): + Connection("CLIENT") # type: ignore + + p = ConnectionPair() + assert p.conn[CLIENT].our_role is CLIENT + assert p.conn[CLIENT].their_role is SERVER + assert p.conn[SERVER].our_role is SERVER + assert p.conn[SERVER].their_role is CLIENT + + data = p.send( + CLIENT, + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Content-Length", "10")], + ), + ) + assert data == ( + b"GET / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 10\r\n\r\n" + ) + + for conn in p.conns: + assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + assert p.conn[CLIENT].our_state is SEND_BODY + assert p.conn[CLIENT].their_state is SEND_RESPONSE + assert p.conn[SERVER].our_state is SEND_RESPONSE + assert p.conn[SERVER].their_state is SEND_BODY + + assert p.conn[CLIENT].their_http_version is None + assert p.conn[SERVER].their_http_version == b"1.1" + + data = p.send(SERVER, InformationalResponse(status_code=100, headers=[])) # type: ignore[arg-type] + assert data == b"HTTP/1.1 100 \r\n\r\n" + + data = p.send(SERVER, Response(status_code=200, headers=[("Content-Length", "11")])) + assert data == b"HTTP/1.1 200 \r\nContent-Length: 11\r\n\r\n" + + for conn in p.conns: + assert conn.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} + + assert p.conn[CLIENT].their_http_version == b"1.1" + assert p.conn[SERVER].their_http_version == b"1.1" + + data = p.send(CLIENT, Data(data=b"12345")) + assert data == b"12345" + data = p.send( + CLIENT, Data(data=b"67890"), expect=[Data(data=b"67890"), EndOfMessage()] + ) + assert data == b"67890" + data = p.send(CLIENT, EndOfMessage(), expect=[]) + assert data == b"" + + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} + + data = p.send(SERVER, Data(data=b"1234567890")) + assert data == b"1234567890" + data = p.send(SERVER, Data(data=b"1"), expect=[Data(data=b"1"), EndOfMessage()]) + assert data == b"1" + data = p.send(SERVER, EndOfMessage(), expect=[]) + assert data == b"" + + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: DONE} + + +def test_chunked() -> None: + p = ConnectionPair() + + p.send( + CLIENT, + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], + ), + ) + data = p.send(CLIENT, Data(data=b"1234567890", chunk_start=True, chunk_end=True)) + assert data == b"a\r\n1234567890\r\n" + data = p.send(CLIENT, Data(data=b"abcde", chunk_start=True, chunk_end=True)) + assert data == b"5\r\nabcde\r\n" + data = p.send(CLIENT, Data(data=b""), expect=[]) + assert data == b"" + data = p.send(CLIENT, EndOfMessage(headers=[("hello", "there")])) + assert data == b"0\r\nhello: there\r\n\r\n" + + p.send( + SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) + ) + p.send(SERVER, Data(data=b"54321", chunk_start=True, chunk_end=True)) + p.send(SERVER, Data(data=b"12345", chunk_start=True, chunk_end=True)) + p.send(SERVER, EndOfMessage()) + + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: DONE} + + +def test_chunk_boundaries() -> None: + conn = Connection(our_role=SERVER) + + request = ( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + ) + conn.receive_data(request) + assert conn.next_event() == Request( + method="POST", + target="/", + headers=[("Host", "example.com"), ("Transfer-Encoding", "chunked")], + ) + assert conn.next_event() is NEED_DATA + + conn.receive_data(b"5\r\nhello\r\n") + assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) + + conn.receive_data(b"5\r\nhel") + assert conn.next_event() == Data(data=b"hel", chunk_start=True, chunk_end=False) + + conn.receive_data(b"l") + assert conn.next_event() == Data(data=b"l", chunk_start=False, chunk_end=False) + + conn.receive_data(b"o\r\n") + assert conn.next_event() == Data(data=b"o", chunk_start=False, chunk_end=True) + + conn.receive_data(b"5\r\nhello") + assert conn.next_event() == Data(data=b"hello", chunk_start=True, chunk_end=True) + + conn.receive_data(b"\r\n") + assert conn.next_event() == NEED_DATA + + conn.receive_data(b"0\r\n\r\n") + assert conn.next_event() == EndOfMessage() + + +def test_client_talking_to_http10_server() -> None: + c = Connection(CLIENT) + c.send(Request(method="GET", target="/", headers=[("Host", "example.com")])) + c.send(EndOfMessage()) + assert c.our_state is DONE + # No content-length, so Http10 framing for body + assert receive_and_get(c, b"HTTP/1.0 200 OK\r\n\r\n") == [ + Response(status_code=200, headers=[], http_version="1.0", reason=b"OK") # type: ignore[arg-type] + ] + assert c.our_state is MUST_CLOSE + assert receive_and_get(c, b"12345") == [Data(data=b"12345")] + assert receive_and_get(c, b"67890") == [Data(data=b"67890")] + assert receive_and_get(c, b"") == [EndOfMessage(), ConnectionClosed()] + assert c.their_state is CLOSED + + +def test_server_talking_to_http10_client() -> None: + c = Connection(SERVER) + # No content-length, so no body + # NB: no host header + assert receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") == [ + Request(method="GET", target="/", headers=[], http_version="1.0"), # type: ignore[arg-type] + EndOfMessage(), + ] + assert c.their_state is MUST_CLOSE + + # We automatically Connection: close back at them + assert ( + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" + ) + + assert c.send(Data(data=b"12345")) == b"12345" + assert c.send(EndOfMessage()) == b"" + assert c.our_state is MUST_CLOSE + + # Check that it works if they do send Content-Length + c = Connection(SERVER) + # NB: no host header + assert receive_and_get(c, b"POST / HTTP/1.0\r\nContent-Length: 10\r\n\r\n1") == [ + Request( + method="POST", + target="/", + headers=[("Content-Length", "10")], + http_version="1.0", + ), + Data(data=b"1"), + ] + assert receive_and_get(c, b"234567890") == [Data(data=b"234567890"), EndOfMessage()] + assert c.their_state is MUST_CLOSE + assert receive_and_get(c, b"") == [ConnectionClosed()] + + +def test_automatic_transfer_encoding_in_response() -> None: + # Check that in responses, the user can specify either Transfer-Encoding: + # chunked or no framing at all, and in both cases we automatically select + # the right option depending on whether the peer speaks HTTP/1.0 or + # HTTP/1.1 + for user_headers in [ + [("Transfer-Encoding", "chunked")], + [], + # In fact, this even works if Content-Length is set, + # because if both are set then Transfer-Encoding wins + [("Transfer-Encoding", "chunked"), ("Content-Length", "100")], + ]: + user_headers = cast(List[Tuple[str, str]], user_headers) + p = ConnectionPair() + p.send( + CLIENT, + [ + Request(method="GET", target="/", headers=[("Host", "example.com")]), + EndOfMessage(), + ], + ) + # When speaking to HTTP/1.1 client, all of the above cases get + # normalized to Transfer-Encoding: chunked + p.send( + SERVER, + Response(status_code=200, headers=user_headers), + expect=Response( + status_code=200, headers=[("Transfer-Encoding", "chunked")] + ), + ) + + # When speaking to HTTP/1.0 client, all of the above cases get + # normalized to no-framing-headers + c = Connection(SERVER) + receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") + assert ( + c.send(Response(status_code=200, headers=user_headers)) + == b"HTTP/1.1 200 \r\nConnection: close\r\n\r\n" + ) + assert c.send(Data(data=b"12345")) == b"12345" + + +def test_automagic_connection_close_handling() -> None: + p = ConnectionPair() + # If the user explicitly sets Connection: close, then we notice and + # respect it + p.send( + CLIENT, + [ + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Connection", "close")], + ), + EndOfMessage(), + ], + ) + for conn in p.conns: + assert conn.states[CLIENT] is MUST_CLOSE + # And if the client sets it, the server automatically echoes it back + p.send( + SERVER, + # no header here... + [Response(status_code=204, headers=[]), EndOfMessage()], # type: ignore[arg-type] + # ...but oh look, it arrived anyway + expect=[ + Response(status_code=204, headers=[("connection", "close")]), + EndOfMessage(), + ], + ) + for conn in p.conns: + assert conn.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} + + +def test_100_continue() -> None: + def setup() -> ConnectionPair: + p = ConnectionPair() + p.send( + CLIENT, + Request( + method="GET", + target="/", + headers=[ + ("Host", "example.com"), + ("Content-Length", "100"), + ("Expect", "100-continue"), + ], + ), + ) + for conn in p.conns: + assert conn.client_is_waiting_for_100_continue + assert not p.conn[CLIENT].they_are_waiting_for_100_continue + assert p.conn[SERVER].they_are_waiting_for_100_continue + return p + + # Disabled by 100 Continue + p = setup() + p.send(SERVER, InformationalResponse(status_code=100, headers=[])) # type: ignore[arg-type] + for conn in p.conns: + assert not conn.client_is_waiting_for_100_continue + assert not conn.they_are_waiting_for_100_continue + + # Disabled by a real response + p = setup() + p.send( + SERVER, Response(status_code=200, headers=[("Transfer-Encoding", "chunked")]) + ) + for conn in p.conns: + assert not conn.client_is_waiting_for_100_continue + assert not conn.they_are_waiting_for_100_continue + + # Disabled by the client going ahead and sending stuff anyway + p = setup() + p.send(CLIENT, Data(data=b"12345")) + for conn in p.conns: + assert not conn.client_is_waiting_for_100_continue + assert not conn.they_are_waiting_for_100_continue + + +def test_max_incomplete_event_size_countermeasure() -> None: + # Infinitely long headers are definitely not okay + c = Connection(SERVER) + c.receive_data(b"GET / HTTP/1.0\r\nEndless: ") + assert c.next_event() is NEED_DATA + with pytest.raises(RemoteProtocolError): + while True: + c.receive_data(b"a" * 1024) + c.next_event() + + # Checking that the same header is accepted / rejected depending on the + # max_incomplete_event_size setting: + c = Connection(SERVER, max_incomplete_event_size=5000) + c.receive_data(b"GET / HTTP/1.0\r\nBig: ") + c.receive_data(b"a" * 4000) + c.receive_data(b"\r\n\r\n") + assert get_all_events(c) == [ + Request( + method="GET", target="/", http_version="1.0", headers=[("big", "a" * 4000)] + ), + EndOfMessage(), + ] + + c = Connection(SERVER, max_incomplete_event_size=4000) + c.receive_data(b"GET / HTTP/1.0\r\nBig: ") + c.receive_data(b"a" * 4000) + with pytest.raises(RemoteProtocolError): + c.next_event() + + # Temporarily exceeding the size limit is fine, as long as its done with + # complete events: + c = Connection(SERVER, max_incomplete_event_size=5000) + c.receive_data(b"GET / HTTP/1.0\r\nContent-Length: 10000") + c.receive_data(b"\r\n\r\n" + b"a" * 10000) + assert get_all_events(c) == [ + Request( + method="GET", + target="/", + http_version="1.0", + headers=[("Content-Length", "10000")], + ), + Data(data=b"a" * 10000), + EndOfMessage(), + ] + + c = Connection(SERVER, max_incomplete_event_size=100) + # Two pipelined requests to create a way-too-big receive buffer... but + # it's fine because we're not checking + c.receive_data( + b"GET /1 HTTP/1.1\r\nHost: a\r\n\r\n" + b"GET /2 HTTP/1.1\r\nHost: b\r\n\r\n" + b"X" * 1000 + ) + assert get_all_events(c) == [ + Request(method="GET", target="/1", headers=[("host", "a")]), + EndOfMessage(), + ] + # Even more data comes in, still no problem + c.receive_data(b"X" * 1000) + # We can respond and reuse to get the second pipelined request + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + c.start_next_cycle() + assert get_all_events(c) == [ + Request(method="GET", target="/2", headers=[("host", "b")]), + EndOfMessage(), + ] + # But once we unpause and try to read the next message, and find that it's + # incomplete and the buffer is *still* way too large, then *that's* a + # problem: + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + c.start_next_cycle() + with pytest.raises(RemoteProtocolError): + c.next_event() + + +def test_reuse_simple() -> None: + p = ConnectionPair() + p.send( + CLIENT, + [Request(method="GET", target="/", headers=[("Host", "a")]), EndOfMessage()], + ) + p.send( + SERVER, + [ + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + EndOfMessage(), + ], + ) + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: DONE} + conn.start_next_cycle() + + p.send( + CLIENT, + [ + Request(method="DELETE", target="/foo", headers=[("Host", "a")]), + EndOfMessage(), + ], + ) + p.send( + SERVER, + [ + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + EndOfMessage(), + ], + ) + + +def test_pipelining() -> None: + # Client doesn't support pipelining, so we have to do this by hand + c = Connection(SERVER) + assert c.next_event() is NEED_DATA + # 3 requests all bunched up + c.receive_data( + b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"12345" + b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"67890" + b"GET /3 HTTP/1.1\r\nHost: a.com\r\n\r\n" + ) + assert get_all_events(c) == [ + Request( + method="GET", + target="/1", + headers=[("Host", "a.com"), ("Content-Length", "5")], + ), + Data(data=b"12345"), + EndOfMessage(), + ] + assert c.their_state is DONE + assert c.our_state is SEND_RESPONSE + + assert c.next_event() is PAUSED + + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + assert c.their_state is DONE + assert c.our_state is DONE + + c.start_next_cycle() + + assert get_all_events(c) == [ + Request( + method="GET", + target="/2", + headers=[("Host", "a.com"), ("Content-Length", "5")], + ), + Data(data=b"67890"), + EndOfMessage(), + ] + assert c.next_event() is PAUSED + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + c.start_next_cycle() + + assert get_all_events(c) == [ + Request(method="GET", target="/3", headers=[("Host", "a.com")]), + EndOfMessage(), + ] + # Doesn't pause this time, no trailing data + assert c.next_event() is NEED_DATA + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + + # Arrival of more data triggers pause + assert c.next_event() is NEED_DATA + c.receive_data(b"SADF") + assert c.next_event() is PAUSED + assert c.trailing_data == (b"SADF", False) + # If EOF arrives while paused, we don't see that either: + c.receive_data(b"") + assert c.trailing_data == (b"SADF", True) + assert c.next_event() is PAUSED + c.receive_data(b"") + assert c.next_event() is PAUSED + # Can't call receive_data with non-empty buf after closing it + with pytest.raises(RuntimeError): + c.receive_data(b"FDSA") + + +def test_protocol_switch() -> None: + for (req, deny, accept) in [ + ( + Request( + method="CONNECT", + target="example.com:443", + headers=[("Host", "foo"), ("Content-Length", "1")], + ), + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + ), + ( + Request( + method="GET", + target="/", + headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], + ), + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + InformationalResponse(status_code=101, headers=[("Upgrade", "a")]), + ), + ( + Request( + method="CONNECT", + target="example.com:443", + headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], + ), + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + # Accept CONNECT, not upgrade + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + ), + ( + Request( + method="CONNECT", + target="example.com:443", + headers=[("Host", "foo"), ("Content-Length", "1"), ("Upgrade", "a, b")], + ), + Response(status_code=404, headers=[(b"transfer-encoding", b"chunked")]), + # Accept Upgrade, not CONNECT + InformationalResponse(status_code=101, headers=[("Upgrade", "b")]), + ), + ]: + + def setup() -> ConnectionPair: + p = ConnectionPair() + p.send(CLIENT, req) + # No switch-related state change stuff yet; the client has to + # finish the request before that kicks in + for conn in p.conns: + assert conn.states[CLIENT] is SEND_BODY + p.send(CLIENT, [Data(data=b"1"), EndOfMessage()]) + for conn in p.conns: + assert conn.states[CLIENT] is MIGHT_SWITCH_PROTOCOL + assert p.conn[SERVER].next_event() is PAUSED + return p + + # Test deny case + p = setup() + p.send(SERVER, deny) + for conn in p.conns: + assert conn.states == {CLIENT: DONE, SERVER: SEND_BODY} + p.send(SERVER, EndOfMessage()) + # Check that re-use is still allowed after a denial + for conn in p.conns: + conn.start_next_cycle() + + # Test accept case + p = setup() + p.send(SERVER, accept) + for conn in p.conns: + assert conn.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} + conn.receive_data(b"123") + assert conn.next_event() is PAUSED + conn.receive_data(b"456") + assert conn.next_event() is PAUSED + assert conn.trailing_data == (b"123456", False) + + # Pausing in might-switch, then recovery + # (weird artificial case where the trailing data actually is valid + # HTTP for some reason, because this makes it easier to test the state + # logic) + p = setup() + sc = p.conn[SERVER] + sc.receive_data(b"GET / HTTP/1.0\r\n\r\n") + assert sc.next_event() is PAUSED + assert sc.trailing_data == (b"GET / HTTP/1.0\r\n\r\n", False) + sc.send(deny) + assert sc.next_event() is PAUSED + sc.send(EndOfMessage()) + sc.start_next_cycle() + assert get_all_events(sc) == [ + Request(method="GET", target="/", headers=[], http_version="1.0"), # type: ignore[arg-type] + EndOfMessage(), + ] + + # When we're DONE, have no trailing data, and the connection gets + # closed, we report ConnectionClosed(). When we're in might-switch or + # switched, we don't. + p = setup() + sc = p.conn[SERVER] + sc.receive_data(b"") + assert sc.next_event() is PAUSED + assert sc.trailing_data == (b"", True) + p.send(SERVER, accept) + assert sc.next_event() is PAUSED + + p = setup() + sc = p.conn[SERVER] + sc.receive_data(b"") + assert sc.next_event() is PAUSED + sc.send(deny) + assert sc.next_event() == ConnectionClosed() + + # You can't send after switching protocols, or while waiting for a + # protocol switch + p = setup() + with pytest.raises(LocalProtocolError): + p.conn[CLIENT].send( + Request(method="GET", target="/", headers=[("Host", "a")]) + ) + p = setup() + p.send(SERVER, accept) + with pytest.raises(LocalProtocolError): + p.conn[SERVER].send(Data(data=b"123")) + + +def test_close_simple() -> None: + # Just immediately closing a new connection without anything having + # happened yet. + for (who_shot_first, who_shot_second) in [(CLIENT, SERVER), (SERVER, CLIENT)]: + + def setup() -> ConnectionPair: + p = ConnectionPair() + p.send(who_shot_first, ConnectionClosed()) + for conn in p.conns: + assert conn.states == { + who_shot_first: CLOSED, + who_shot_second: MUST_CLOSE, + } + return p + + # You can keep putting b"" into a closed connection, and you keep + # getting ConnectionClosed() out: + p = setup() + assert p.conn[who_shot_second].next_event() == ConnectionClosed() + assert p.conn[who_shot_second].next_event() == ConnectionClosed() + p.conn[who_shot_second].receive_data(b"") + assert p.conn[who_shot_second].next_event() == ConnectionClosed() + # Second party can close... + p = setup() + p.send(who_shot_second, ConnectionClosed()) + for conn in p.conns: + assert conn.our_state is CLOSED + assert conn.their_state is CLOSED + # But trying to receive new data on a closed connection is a + # RuntimeError (not ProtocolError, because the problem here isn't + # violation of HTTP, it's violation of physics) + p = setup() + with pytest.raises(RuntimeError): + p.conn[who_shot_second].receive_data(b"123") + # And receiving new data on a MUST_CLOSE connection is a ProtocolError + p = setup() + p.conn[who_shot_first].receive_data(b"GET") + with pytest.raises(RemoteProtocolError): + p.conn[who_shot_first].next_event() + + +def test_close_different_states() -> None: + req = [ + Request(method="GET", target="/foo", headers=[("Host", "a")]), + EndOfMessage(), + ] + resp = [ + Response(status_code=200, headers=[(b"transfer-encoding", b"chunked")]), + EndOfMessage(), + ] + + # Client before request + p = ConnectionPair() + p.send(CLIENT, ConnectionClosed()) + for conn in p.conns: + assert conn.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} + + # Client after request + p = ConnectionPair() + p.send(CLIENT, req) + p.send(CLIENT, ConnectionClosed()) + for conn in p.conns: + assert conn.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} + + # Server after request -> not allowed + p = ConnectionPair() + p.send(CLIENT, req) + with pytest.raises(LocalProtocolError): + p.conn[SERVER].send(ConnectionClosed()) + p.conn[CLIENT].receive_data(b"") + with pytest.raises(RemoteProtocolError): + p.conn[CLIENT].next_event() + + # Server after response + p = ConnectionPair() + p.send(CLIENT, req) + p.send(SERVER, resp) + p.send(SERVER, ConnectionClosed()) + for conn in p.conns: + assert conn.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} + + # Both after closing (ConnectionClosed() is idempotent) + p = ConnectionPair() + p.send(CLIENT, req) + p.send(SERVER, resp) + p.send(CLIENT, ConnectionClosed()) + p.send(SERVER, ConnectionClosed()) + p.send(CLIENT, ConnectionClosed()) + p.send(SERVER, ConnectionClosed()) + + # In the middle of sending -> not allowed + p = ConnectionPair() + p.send( + CLIENT, + Request( + method="GET", target="/", headers=[("Host", "a"), ("Content-Length", "10")] + ), + ) + with pytest.raises(LocalProtocolError): + p.conn[CLIENT].send(ConnectionClosed()) + p.conn[SERVER].receive_data(b"") + with pytest.raises(RemoteProtocolError): + p.conn[SERVER].next_event() + + +# Receive several requests and then client shuts down their side of the +# connection; we can respond to each +def test_pipelined_close() -> None: + c = Connection(SERVER) + # 2 requests then a close + c.receive_data( + b"GET /1 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"12345" + b"GET /2 HTTP/1.1\r\nHost: a.com\r\nContent-Length: 5\r\n\r\n" + b"67890" + ) + c.receive_data(b"") + assert get_all_events(c) == [ + Request( + method="GET", + target="/1", + headers=[("host", "a.com"), ("content-length", "5")], + ), + Data(data=b"12345"), + EndOfMessage(), + ] + assert c.states[CLIENT] is DONE + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + assert c.states[SERVER] is DONE + c.start_next_cycle() + assert get_all_events(c) == [ + Request( + method="GET", + target="/2", + headers=[("host", "a.com"), ("content-length", "5")], + ), + Data(data=b"67890"), + EndOfMessage(), + ConnectionClosed(), + ] + assert c.states == {CLIENT: CLOSED, SERVER: SEND_RESPONSE} + c.send(Response(status_code=200, headers=[])) # type: ignore[arg-type] + c.send(EndOfMessage()) + assert c.states == {CLIENT: CLOSED, SERVER: MUST_CLOSE} + c.send(ConnectionClosed()) + assert c.states == {CLIENT: CLOSED, SERVER: CLOSED} + + +def test_sendfile() -> None: + class SendfilePlaceholder: + def __len__(self) -> int: + return 10 + + placeholder = SendfilePlaceholder() + + def setup( + header: Tuple[str, str], http_version: str + ) -> Tuple[Connection, Optional[List[bytes]]]: + c = Connection(SERVER) + receive_and_get( + c, "GET / HTTP/{}\r\nHost: a\r\n\r\n".format(http_version).encode("ascii") + ) + headers = [] + if header: + headers.append(header) + c.send(Response(status_code=200, headers=headers)) + return c, c.send_with_data_passthrough(Data(data=placeholder)) # type: ignore + + c, data = setup(("Content-Length", "10"), "1.1") + assert data == [placeholder] # type: ignore + # Raises an error if the connection object doesn't think we've sent + # exactly 10 bytes + c.send(EndOfMessage()) + + _, data = setup(("Transfer-Encoding", "chunked"), "1.1") + assert placeholder in data # type: ignore + data[data.index(placeholder)] = b"x" * 10 # type: ignore + assert b"".join(data) == b"a\r\nxxxxxxxxxx\r\n" # type: ignore + + c, data = setup(None, "1.0") # type: ignore + assert data == [placeholder] # type: ignore + assert c.our_state is SEND_BODY + + +def test_errors() -> None: + # After a receive error, you can't receive + for role in [CLIENT, SERVER]: + c = Connection(our_role=role) + c.receive_data(b"gibberish\r\n\r\n") + with pytest.raises(RemoteProtocolError): + c.next_event() + # Now any attempt to receive continues to raise + assert c.their_state is ERROR + assert c.our_state is not ERROR + print(c._cstate.states) + with pytest.raises(RemoteProtocolError): + c.next_event() + # But we can still yell at the client for sending us gibberish + if role is SERVER: + assert ( + c.send(Response(status_code=400, headers=[])) # type: ignore[arg-type] + == b"HTTP/1.1 400 \r\nConnection: close\r\n\r\n" + ) + + # After an error sending, you can no longer send + # (This is especially important for things like content-length errors, + # where there's complex internal state being modified) + def conn(role: Type[Sentinel]) -> Connection: + c = Connection(our_role=role) + if role is SERVER: + # Put it into the state where it *could* send a response... + receive_and_get(c, b"GET / HTTP/1.0\r\n\r\n") + assert c.our_state is SEND_RESPONSE + return c + + for role in [CLIENT, SERVER]: + if role is CLIENT: + # This HTTP/1.0 request won't be detected as bad until after we go + # through the state machine and hit the writing code + good = Request(method="GET", target="/", headers=[("Host", "example.com")]) + bad = Request( + method="GET", + target="/", + headers=[("Host", "example.com")], + http_version="1.0", + ) + elif role is SERVER: + good = Response(status_code=200, headers=[]) # type: ignore[arg-type,assignment] + bad = Response(status_code=200, headers=[], http_version="1.0") # type: ignore[arg-type,assignment] + # Make sure 'good' actually is good + c = conn(role) + c.send(good) + assert c.our_state is not ERROR + # Do that again, but this time sending 'bad' first + c = conn(role) + with pytest.raises(LocalProtocolError): + c.send(bad) + assert c.our_state is ERROR + assert c.their_state is not ERROR + # Now 'good' is not so good + with pytest.raises(LocalProtocolError): + c.send(good) + + # And check send_failed() too + c = conn(role) + c.send_failed() + assert c.our_state is ERROR + assert c.their_state is not ERROR + # This is idempotent + c.send_failed() + assert c.our_state is ERROR + assert c.their_state is not ERROR + + +def test_idle_receive_nothing() -> None: + # At one point this incorrectly raised an error + for role in [CLIENT, SERVER]: + c = Connection(role) + assert c.next_event() is NEED_DATA + + +def test_connection_drop() -> None: + c = Connection(SERVER) + c.receive_data(b"GET /") + assert c.next_event() is NEED_DATA + c.receive_data(b"") + with pytest.raises(RemoteProtocolError): + c.next_event() + + +def test_408_request_timeout() -> None: + # Should be able to send this spontaneously as a server without seeing + # anything from client + p = ConnectionPair() + p.send(SERVER, Response(status_code=408, headers=[(b"connection", b"close")])) + + +# This used to raise IndexError +def test_empty_request() -> None: + c = Connection(SERVER) + c.receive_data(b"\r\n") + with pytest.raises(RemoteProtocolError): + c.next_event() + + +# This used to raise IndexError +def test_empty_response() -> None: + c = Connection(CLIENT) + c.send(Request(method="GET", target="/", headers=[("Host", "a")])) + c.receive_data(b"\r\n") + with pytest.raises(RemoteProtocolError): + c.next_event() + + +@pytest.mark.parametrize( + "data", + [ + b"\x00", + b"\x20", + b"\x16\x03\x01\x00\xa5", # Typical start of a TLS Client Hello + ], +) +def test_early_detection_of_invalid_request(data: bytes) -> None: + c = Connection(SERVER) + # Early detection should occur before even receiving a `\r\n` + c.receive_data(data) + with pytest.raises(RemoteProtocolError): + c.next_event() + + +@pytest.mark.parametrize( + "data", + [ + b"\x00", + b"\x20", + b"\x16\x03\x03\x00\x31", # Typical start of a TLS Server Hello + ], +) +def test_early_detection_of_invalid_response(data: bytes) -> None: + c = Connection(CLIENT) + # Early detection should occur before even receiving a `\r\n` + c.receive_data(data) + with pytest.raises(RemoteProtocolError): + c.next_event() + + +# This used to give different headers for HEAD and GET. +# The correct way to handle HEAD is to put whatever headers we *would* have +# put if it were a GET -- even though we know that for HEAD, those headers +# will be ignored. +def test_HEAD_framing_headers() -> None: + def setup(method: bytes, http_version: bytes) -> Connection: + c = Connection(SERVER) + c.receive_data( + method + b" / HTTP/" + http_version + b"\r\n" + b"Host: example.com\r\n\r\n" + ) + assert type(c.next_event()) is Request + assert type(c.next_event()) is EndOfMessage + return c + + for method in [b"GET", b"HEAD"]: + # No Content-Length, HTTP/1.1 peer, should use chunked + c = setup(method, b"1.1") + assert ( + c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" # type: ignore[arg-type] + b"Transfer-Encoding: chunked\r\n\r\n" + ) + + # No Content-Length, HTTP/1.0 peer, frame with connection: close + c = setup(method, b"1.0") + assert ( + c.send(Response(status_code=200, headers=[])) == b"HTTP/1.1 200 \r\n" # type: ignore[arg-type] + b"Connection: close\r\n\r\n" + ) + + # Content-Length + Transfer-Encoding, TE wins + c = setup(method, b"1.1") + assert ( + c.send( + Response( + status_code=200, + headers=[ + ("Content-Length", "100"), + ("Transfer-Encoding", "chunked"), + ], + ) + ) + == b"HTTP/1.1 200 \r\n" + b"Transfer-Encoding: chunked\r\n\r\n" + ) + + +def test_special_exceptions_for_lost_connection_in_message_body() -> None: + c = Connection(SERVER) + c.receive_data( + b"POST / HTTP/1.1\r\n" b"Host: example.com\r\n" b"Content-Length: 100\r\n\r\n" + ) + assert type(c.next_event()) is Request + assert c.next_event() is NEED_DATA + c.receive_data(b"12345") + assert c.next_event() == Data(data=b"12345") + c.receive_data(b"") + with pytest.raises(RemoteProtocolError) as excinfo: + c.next_event() + assert "received 5 bytes" in str(excinfo.value) + assert "expected 100" in str(excinfo.value) + + c = Connection(SERVER) + c.receive_data( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Transfer-Encoding: chunked\r\n\r\n" + ) + assert type(c.next_event()) is Request + assert c.next_event() is NEED_DATA + c.receive_data(b"8\r\n012345") + assert c.next_event().data == b"012345" # type: ignore + c.receive_data(b"") + with pytest.raises(RemoteProtocolError) as excinfo: + c.next_event() + assert "incomplete chunked read" in str(excinfo.value) diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_events.py b/venv/lib/python3.11/site-packages/h11/tests/test_events.py new file mode 100644 index 0000000..bc6c313 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_events.py @@ -0,0 +1,150 @@ +from http import HTTPStatus + +import pytest + +from .. import _events +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._util import LocalProtocolError + + +def test_events() -> None: + with pytest.raises(LocalProtocolError): + # Missing Host: + req = Request( + method="GET", target="/", headers=[("a", "b")], http_version="1.1" + ) + # But this is okay (HTTP/1.0) + req = Request(method="GET", target="/", headers=[("a", "b")], http_version="1.0") + # fields are normalized + assert req.method == b"GET" + assert req.target == b"/" + assert req.headers == [(b"a", b"b")] + assert req.http_version == b"1.0" + + # This is also okay -- has a Host (with weird capitalization, which is ok) + req = Request( + method="GET", + target="/", + headers=[("a", "b"), ("hOSt", "example.com")], + http_version="1.1", + ) + # we normalize header capitalization + assert req.headers == [(b"a", b"b"), (b"host", b"example.com")] + + # Multiple host is bad too + with pytest.raises(LocalProtocolError): + req = Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Host", "a")], + http_version="1.1", + ) + # Even for HTTP/1.0 + with pytest.raises(LocalProtocolError): + req = Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Host", "a")], + http_version="1.0", + ) + + # Header values are validated + for bad_char in "\x00\r\n\f\v": + with pytest.raises(LocalProtocolError): + req = Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Foo", "asd" + bad_char)], + http_version="1.0", + ) + + # But for compatibility we allow non-whitespace control characters, even + # though they're forbidden by the spec. + Request( + method="GET", + target="/", + headers=[("Host", "a"), ("Foo", "asd\x01\x02\x7f")], + http_version="1.0", + ) + + # Request target is validated + for bad_byte in b"\x00\x20\x7f\xee": + target = bytearray(b"/") + target.append(bad_byte) + with pytest.raises(LocalProtocolError): + Request( + method="GET", target=target, headers=[("Host", "a")], http_version="1.1" + ) + + # Request method is validated + with pytest.raises(LocalProtocolError): + Request( + method="GET / HTTP/1.1", + target=target, + headers=[("Host", "a")], + http_version="1.1", + ) + + ir = InformationalResponse(status_code=100, headers=[("Host", "a")]) + assert ir.status_code == 100 + assert ir.headers == [(b"host", b"a")] + assert ir.http_version == b"1.1" + + with pytest.raises(LocalProtocolError): + InformationalResponse(status_code=200, headers=[("Host", "a")]) + + resp = Response(status_code=204, headers=[], http_version="1.0") # type: ignore[arg-type] + assert resp.status_code == 204 + assert resp.headers == [] + assert resp.http_version == b"1.0" + + with pytest.raises(LocalProtocolError): + resp = Response(status_code=100, headers=[], http_version="1.0") # type: ignore[arg-type] + + with pytest.raises(LocalProtocolError): + Response(status_code="100", headers=[], http_version="1.0") # type: ignore[arg-type] + + with pytest.raises(LocalProtocolError): + InformationalResponse(status_code=b"100", headers=[], http_version="1.0") # type: ignore[arg-type] + + d = Data(data=b"asdf") + assert d.data == b"asdf" + + eom = EndOfMessage() + assert eom.headers == [] + + cc = ConnectionClosed() + assert repr(cc) == "ConnectionClosed()" + + +def test_intenum_status_code() -> None: + # https://github.com/python-hyper/h11/issues/72 + + r = Response(status_code=HTTPStatus.OK, headers=[], http_version="1.0") # type: ignore[arg-type] + assert r.status_code == HTTPStatus.OK + assert type(r.status_code) is not type(HTTPStatus.OK) + assert type(r.status_code) is int + + +def test_header_casing() -> None: + r = Request( + method="GET", + target="/", + headers=[("Host", "example.org"), ("Connection", "keep-alive")], + http_version="1.1", + ) + assert len(r.headers) == 2 + assert r.headers[0] == (b"host", b"example.org") + assert r.headers == [(b"host", b"example.org"), (b"connection", b"keep-alive")] + assert r.headers.raw_items() == [ + (b"Host", b"example.org"), + (b"Connection", b"keep-alive"), + ] diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_headers.py b/venv/lib/python3.11/site-packages/h11/tests/test_headers.py new file mode 100644 index 0000000..ba53d08 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_headers.py @@ -0,0 +1,157 @@ +import pytest + +from .._events import Request +from .._headers import ( + get_comma_header, + has_expect_100_continue, + Headers, + normalize_and_validate, + set_comma_header, +) +from .._util import LocalProtocolError + + +def test_normalize_and_validate() -> None: + assert normalize_and_validate([("foo", "bar")]) == [(b"foo", b"bar")] + assert normalize_and_validate([(b"foo", b"bar")]) == [(b"foo", b"bar")] + + # no leading/trailing whitespace in names + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo ", "bar")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b" foo", "bar")]) + + # no weird characters in names + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate([(b"foo bar", b"baz")]) + assert "foo bar" in str(excinfo.value) + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo\x00bar", b"baz")]) + # Not even 8-bit characters: + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo\xffbar", b"baz")]) + # And not even the control characters we allow in values: + with pytest.raises(LocalProtocolError): + normalize_and_validate([(b"foo\x01bar", b"baz")]) + + # no return or NUL characters in values + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate([("foo", "bar\rbaz")]) + assert "bar\\rbaz" in str(excinfo.value) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "bar\nbaz")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "bar\x00baz")]) + # no leading/trailing whitespace + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "barbaz ")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", " barbaz")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "barbaz\t")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("foo", "\tbarbaz")]) + + # content-length + assert normalize_and_validate([("Content-Length", "1")]) == [ + (b"content-length", b"1") + ] + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "asdf")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "1x")]) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "1"), ("Content-Length", "2")]) + assert normalize_and_validate( + [("Content-Length", "0"), ("Content-Length", "0")] + ) == [(b"content-length", b"0")] + assert normalize_and_validate([("Content-Length", "0 , 0")]) == [ + (b"content-length", b"0") + ] + with pytest.raises(LocalProtocolError): + normalize_and_validate( + [("Content-Length", "1"), ("Content-Length", "1"), ("Content-Length", "2")] + ) + with pytest.raises(LocalProtocolError): + normalize_and_validate([("Content-Length", "1 , 1,2")]) + + # transfer-encoding + assert normalize_and_validate([("Transfer-Encoding", "chunked")]) == [ + (b"transfer-encoding", b"chunked") + ] + assert normalize_and_validate([("Transfer-Encoding", "cHuNkEd")]) == [ + (b"transfer-encoding", b"chunked") + ] + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate([("Transfer-Encoding", "gzip")]) + assert excinfo.value.error_status_hint == 501 # Not Implemented + with pytest.raises(LocalProtocolError) as excinfo: + normalize_and_validate( + [("Transfer-Encoding", "chunked"), ("Transfer-Encoding", "gzip")] + ) + assert excinfo.value.error_status_hint == 501 # Not Implemented + + +def test_get_set_comma_header() -> None: + headers = normalize_and_validate( + [ + ("Connection", "close"), + ("whatever", "something"), + ("connectiON", "fOo,, , BAR"), + ] + ) + + assert get_comma_header(headers, b"connection") == [b"close", b"foo", b"bar"] + + headers = set_comma_header(headers, b"newthing", ["a", "b"]) # type: ignore + + with pytest.raises(LocalProtocolError): + set_comma_header(headers, b"newthing", [" a", "b"]) # type: ignore + + assert headers == [ + (b"connection", b"close"), + (b"whatever", b"something"), + (b"connection", b"fOo,, , BAR"), + (b"newthing", b"a"), + (b"newthing", b"b"), + ] + + headers = set_comma_header(headers, b"whatever", ["different thing"]) # type: ignore + + assert headers == [ + (b"connection", b"close"), + (b"connection", b"fOo,, , BAR"), + (b"newthing", b"a"), + (b"newthing", b"b"), + (b"whatever", b"different thing"), + ] + + +def test_has_100_continue() -> None: + assert has_expect_100_continue( + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Expect", "100-continue")], + ) + ) + assert not has_expect_100_continue( + Request(method="GET", target="/", headers=[("Host", "example.com")]) + ) + # Case insensitive + assert has_expect_100_continue( + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Expect", "100-Continue")], + ) + ) + # Doesn't work in HTTP/1.0 + assert not has_expect_100_continue( + Request( + method="GET", + target="/", + headers=[("Host", "example.com"), ("Expect", "100-continue")], + http_version="1.0", + ) + ) diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_helpers.py b/venv/lib/python3.11/site-packages/h11/tests/test_helpers.py new file mode 100644 index 0000000..c329c76 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_helpers.py @@ -0,0 +1,32 @@ +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .helpers import normalize_data_events + + +def test_normalize_data_events() -> None: + assert normalize_data_events( + [ + Data(data=bytearray(b"1")), + Data(data=b"2"), + Response(status_code=200, headers=[]), # type: ignore[arg-type] + Data(data=b"3"), + Data(data=b"4"), + EndOfMessage(), + Data(data=b"5"), + Data(data=b"6"), + Data(data=b"7"), + ] + ) == [ + Data(data=b"12"), + Response(status_code=200, headers=[]), # type: ignore[arg-type] + Data(data=b"34"), + EndOfMessage(), + Data(data=b"567"), + ] diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_io.py b/venv/lib/python3.11/site-packages/h11/tests/test_io.py new file mode 100644 index 0000000..2b47c0e --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_io.py @@ -0,0 +1,572 @@ +from typing import Any, Callable, Generator, List + +import pytest + +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._headers import Headers, normalize_and_validate +from .._readers import ( + _obsolete_line_fold, + ChunkedReader, + ContentLengthReader, + Http10Reader, + READERS, +) +from .._receivebuffer import ReceiveBuffer +from .._state import ( + CLIENT, + CLOSED, + DONE, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from .._util import LocalProtocolError +from .._writers import ( + ChunkedWriter, + ContentLengthWriter, + Http10Writer, + write_any_response, + write_headers, + write_request, + WRITERS, +) +from .helpers import normalize_data_events + +SIMPLE_CASES = [ + ( + (CLIENT, IDLE), + Request( + method="GET", + target="/a", + headers=[("Host", "foo"), ("Connection", "close")], + ), + b"GET /a HTTP/1.1\r\nHost: foo\r\nConnection: close\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + Response(status_code=200, headers=[("Connection", "close")], reason=b"OK"), + b"HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + Response(status_code=200, headers=[], reason=b"OK"), # type: ignore[arg-type] + b"HTTP/1.1 200 OK\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + InformationalResponse( + status_code=101, headers=[("Upgrade", "websocket")], reason=b"Upgrade" + ), + b"HTTP/1.1 101 Upgrade\r\nUpgrade: websocket\r\n\r\n", + ), + ( + (SERVER, SEND_RESPONSE), + InformationalResponse(status_code=101, headers=[], reason=b"Upgrade"), # type: ignore[arg-type] + b"HTTP/1.1 101 Upgrade\r\n\r\n", + ), +] + + +def dowrite(writer: Callable[..., None], obj: Any) -> bytes: + got_list: List[bytes] = [] + writer(obj, got_list.append) + return b"".join(got_list) + + +def tw(writer: Any, obj: Any, expected: Any) -> None: + got = dowrite(writer, obj) + assert got == expected + + +def makebuf(data: bytes) -> ReceiveBuffer: + buf = ReceiveBuffer() + buf += data + return buf + + +def tr(reader: Any, data: bytes, expected: Any) -> None: + def check(got: Any) -> None: + assert got == expected + # Headers should always be returned as bytes, not e.g. bytearray + # https://github.com/python-hyper/wsproto/pull/54#issuecomment-377709478 + for name, value in getattr(got, "headers", []): + assert type(name) is bytes + assert type(value) is bytes + + # Simple: consume whole thing + buf = makebuf(data) + check(reader(buf)) + assert not buf + + # Incrementally growing buffer + buf = ReceiveBuffer() + for i in range(len(data)): + assert reader(buf) is None + buf += data[i : i + 1] + check(reader(buf)) + + # Trailing data + buf = makebuf(data) + buf += b"trailing" + check(reader(buf)) + assert bytes(buf) == b"trailing" + + +def test_writers_simple() -> None: + for ((role, state), event, binary) in SIMPLE_CASES: + tw(WRITERS[role, state], event, binary) + + +def test_readers_simple() -> None: + for ((role, state), event, binary) in SIMPLE_CASES: + tr(READERS[role, state], binary, event) + + +def test_writers_unusual() -> None: + # Simple test of the write_headers utility routine + tw( + write_headers, + normalize_and_validate([("foo", "bar"), ("baz", "quux")]), + b"foo: bar\r\nbaz: quux\r\n\r\n", + ) + tw(write_headers, Headers([]), b"\r\n") + + # We understand HTTP/1.0, but we don't speak it + with pytest.raises(LocalProtocolError): + tw( + write_request, + Request( + method="GET", + target="/", + headers=[("Host", "foo"), ("Connection", "close")], + http_version="1.0", + ), + None, + ) + with pytest.raises(LocalProtocolError): + tw( + write_any_response, + Response( + status_code=200, headers=[("Connection", "close")], http_version="1.0" + ), + None, + ) + + +def test_readers_unusual() -> None: + # Reading HTTP/1.0 + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.0\r\nSome: header\r\n\r\n", + Request( + method="HEAD", + target="/foo", + headers=[("Some", "header")], + http_version="1.0", + ), + ) + + # check no-headers, since it's only legal with HTTP/1.0 + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.0\r\n\r\n", + Request(method="HEAD", target="/foo", headers=[], http_version="1.0"), # type: ignore[arg-type] + ) + + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\nSome: header\r\n\r\n", + Response( + status_code=200, + headers=[("Some", "header")], + http_version="1.0", + reason=b"OK", + ), + ) + + # single-character header values (actually disallowed by the ABNF in RFC + # 7230 -- this is a bug in the standard that we originally copied...) + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\n" b"Foo: a a a a a \r\n\r\n", + Response( + status_code=200, + headers=[("Foo", "a a a a a")], + http_version="1.0", + reason=b"OK", + ), + ) + + # Empty headers -- also legal + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\n" b"Foo:\r\n\r\n", + Response( + status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" + ), + ) + + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200 OK\r\n" b"Foo: \t \t \r\n\r\n", + Response( + status_code=200, headers=[("Foo", "")], http_version="1.0", reason=b"OK" + ), + ) + + # Tolerate broken servers that leave off the response code + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.0 200\r\n" b"Foo: bar\r\n\r\n", + Response( + status_code=200, headers=[("Foo", "bar")], http_version="1.0", reason=b"" + ), + ) + + # Tolerate headers line endings (\r\n and \n) + # \n\r\b between headers and body + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.1 200 OK\r\nSomeHeader: val\n\r\n", + Response( + status_code=200, + headers=[("SomeHeader", "val")], + http_version="1.1", + reason="OK", + ), + ) + + # delimited only with \n + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.1 200 OK\nSomeHeader1: val1\nSomeHeader2: val2\n\n", + Response( + status_code=200, + headers=[("SomeHeader1", "val1"), ("SomeHeader2", "val2")], + http_version="1.1", + reason="OK", + ), + ) + + # mixed \r\n and \n + tr( + READERS[SERVER, SEND_RESPONSE], + b"HTTP/1.1 200 OK\r\nSomeHeader1: val1\nSomeHeader2: val2\n\r\n", + Response( + status_code=200, + headers=[("SomeHeader1", "val1"), ("SomeHeader2", "val2")], + http_version="1.1", + reason="OK", + ), + ) + + # obsolete line folding + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Some: multi-line\r\n" + b" header\r\n" + b"\tnonsense\r\n" + b" \t \t\tI guess\r\n" + b"Connection: close\r\n" + b"More-nonsense: in the\r\n" + b" last header \r\n\r\n", + Request( + method="HEAD", + target="/foo", + headers=[ + ("Host", "example.com"), + ("Some", "multi-line header nonsense I guess"), + ("Connection", "close"), + ("More-nonsense", "in the last header"), + ], + ), + ) + + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b" folded: line\r\n\r\n", + None, + ) + + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"foo : line\r\n\r\n", + None, + ) + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", + None, + ) + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"foo\t: line\r\n\r\n", + None, + ) + with pytest.raises(LocalProtocolError): + tr(READERS[CLIENT, IDLE], b"HEAD /foo HTTP/1.1\r\n" b": line\r\n\r\n", None) + + +def test__obsolete_line_fold_bytes() -> None: + # _obsolete_line_fold has a defensive cast to bytearray, which is + # necessary to protect against O(n^2) behavior in case anyone ever passes + # in regular bytestrings... but right now we never pass in regular + # bytestrings. so this test just exists to get some coverage on that + # defensive cast. + assert list(_obsolete_line_fold([b"aaa", b"bbb", b" ccc", b"ddd"])) == [ + b"aaa", + bytearray(b"bbb ccc"), + b"ddd", + ] + + +def _run_reader_iter( + reader: Any, buf: bytes, do_eof: bool +) -> Generator[Any, None, None]: + while True: + event = reader(buf) + if event is None: + break + yield event + # body readers have undefined behavior after returning EndOfMessage, + # because this changes the state so they don't get called again + if type(event) is EndOfMessage: + break + if do_eof: + assert not buf + yield reader.read_eof() + + +def _run_reader(*args: Any) -> List[Event]: + events = list(_run_reader_iter(*args)) + return normalize_data_events(events) + + +def t_body_reader(thunk: Any, data: bytes, expected: Any, do_eof: bool = False) -> None: + # Simple: consume whole thing + print("Test 1") + buf = makebuf(data) + assert _run_reader(thunk(), buf, do_eof) == expected + + # Incrementally growing buffer + print("Test 2") + reader = thunk() + buf = ReceiveBuffer() + events = [] + for i in range(len(data)): + events += _run_reader(reader, buf, False) + buf += data[i : i + 1] + events += _run_reader(reader, buf, do_eof) + assert normalize_data_events(events) == expected + + is_complete = any(type(event) is EndOfMessage for event in expected) + if is_complete and not do_eof: + buf = makebuf(data + b"trailing") + assert _run_reader(thunk(), buf, False) == expected + + +def test_ContentLengthReader() -> None: + t_body_reader(lambda: ContentLengthReader(0), b"", [EndOfMessage()]) + + t_body_reader( + lambda: ContentLengthReader(10), + b"0123456789", + [Data(data=b"0123456789"), EndOfMessage()], + ) + + +def test_Http10Reader() -> None: + t_body_reader(Http10Reader, b"", [EndOfMessage()], do_eof=True) + t_body_reader(Http10Reader, b"asdf", [Data(data=b"asdf")], do_eof=False) + t_body_reader( + Http10Reader, b"asdf", [Data(data=b"asdf"), EndOfMessage()], do_eof=True + ) + + +def test_ChunkedReader() -> None: + t_body_reader(ChunkedReader, b"0\r\n\r\n", [EndOfMessage()]) + + t_body_reader( + ChunkedReader, + b"0\r\nSome: header\r\n\r\n", + [EndOfMessage(headers=[("Some", "header")])], + ) + + t_body_reader( + ChunkedReader, + b"5\r\n01234\r\n" + + b"10\r\n0123456789abcdef\r\n" + + b"0\r\n" + + b"Some: header\r\n\r\n", + [ + Data(data=b"012340123456789abcdef"), + EndOfMessage(headers=[("Some", "header")]), + ], + ) + + t_body_reader( + ChunkedReader, + b"5\r\n01234\r\n" + b"10\r\n0123456789abcdef\r\n" + b"0\r\n\r\n", + [Data(data=b"012340123456789abcdef"), EndOfMessage()], + ) + + # handles upper and lowercase hex + t_body_reader( + ChunkedReader, + b"aA\r\n" + b"x" * 0xAA + b"\r\n" + b"0\r\n\r\n", + [Data(data=b"x" * 0xAA), EndOfMessage()], + ) + + # refuses arbitrarily long chunk integers + with pytest.raises(LocalProtocolError): + # Technically this is legal HTTP/1.1, but we refuse to process chunk + # sizes that don't fit into 20 characters of hex + t_body_reader(ChunkedReader, b"9" * 100 + b"\r\nxxx", [Data(data=b"xxx")]) + + # refuses garbage in the chunk count + with pytest.raises(LocalProtocolError): + t_body_reader(ChunkedReader, b"10\x00\r\nxxx", None) + + # handles (and discards) "chunk extensions" omg wtf + t_body_reader( + ChunkedReader, + b"5; hello=there\r\n" + + b"xxxxx" + + b"\r\n" + + b'0; random="junk"; some=more; canbe=lonnnnngg\r\n\r\n', + [Data(data=b"xxxxx"), EndOfMessage()], + ) + + t_body_reader( + ChunkedReader, + b"5 \r\n01234\r\n" + b"0\r\n\r\n", + [Data(data=b"01234"), EndOfMessage()], + ) + + +def test_ContentLengthWriter() -> None: + w = ContentLengthWriter(5) + assert dowrite(w, Data(data=b"123")) == b"123" + assert dowrite(w, Data(data=b"45")) == b"45" + assert dowrite(w, EndOfMessage()) == b"" + + w = ContentLengthWriter(5) + with pytest.raises(LocalProtocolError): + dowrite(w, Data(data=b"123456")) + + w = ContentLengthWriter(5) + dowrite(w, Data(data=b"123")) + with pytest.raises(LocalProtocolError): + dowrite(w, Data(data=b"456")) + + w = ContentLengthWriter(5) + dowrite(w, Data(data=b"123")) + with pytest.raises(LocalProtocolError): + dowrite(w, EndOfMessage()) + + w = ContentLengthWriter(5) + dowrite(w, Data(data=b"123")) == b"123" + dowrite(w, Data(data=b"45")) == b"45" + with pytest.raises(LocalProtocolError): + dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) + + +def test_ChunkedWriter() -> None: + w = ChunkedWriter() + assert dowrite(w, Data(data=b"aaa")) == b"3\r\naaa\r\n" + assert dowrite(w, Data(data=b"a" * 20)) == b"14\r\n" + b"a" * 20 + b"\r\n" + + assert dowrite(w, Data(data=b"")) == b"" + + assert dowrite(w, EndOfMessage()) == b"0\r\n\r\n" + + assert ( + dowrite(w, EndOfMessage(headers=[("Etag", "asdf"), ("a", "b")])) + == b"0\r\nEtag: asdf\r\na: b\r\n\r\n" + ) + + +def test_Http10Writer() -> None: + w = Http10Writer() + assert dowrite(w, Data(data=b"1234")) == b"1234" + assert dowrite(w, EndOfMessage()) == b"" + + with pytest.raises(LocalProtocolError): + dowrite(w, EndOfMessage(headers=[("Etag", "asdf")])) + + +def test_reject_garbage_after_request_line() -> None: + with pytest.raises(LocalProtocolError): + tr(READERS[SERVER, SEND_RESPONSE], b"HTTP/1.0 200 OK\x00xxxx\r\n\r\n", None) + + +def test_reject_garbage_after_response_line() -> None: + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1 xxxxxx\r\n" b"Host: a\r\n\r\n", + None, + ) + + +def test_reject_garbage_in_header_line() -> None: + with pytest.raises(LocalProtocolError): + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" b"Host: foo\x00bar\r\n\r\n", + None, + ) + + +def test_reject_non_vchar_in_path() -> None: + for bad_char in b"\x00\x20\x7f\xee": + message = bytearray(b"HEAD /") + message.append(bad_char) + message.extend(b" HTTP/1.1\r\nHost: foobar\r\n\r\n") + with pytest.raises(LocalProtocolError): + tr(READERS[CLIENT, IDLE], message, None) + + +# https://github.com/python-hyper/h11/issues/57 +def test_allow_some_garbage_in_cookies() -> None: + tr( + READERS[CLIENT, IDLE], + b"HEAD /foo HTTP/1.1\r\n" + b"Host: foo\r\n" + b"Set-Cookie: ___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900\r\n" + b"\r\n", + Request( + method="HEAD", + target="/foo", + headers=[ + ("Host", "foo"), + ("Set-Cookie", "___utmvafIumyLc=kUd\x01UpAt; path=/; Max-Age=900"), + ], + ), + ) + + +def test_host_comes_first() -> None: + tw( + write_headers, + normalize_and_validate([("foo", "bar"), ("Host", "example.com")]), + b"Host: example.com\r\nfoo: bar\r\n\r\n", + ) diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_receivebuffer.py b/venv/lib/python3.11/site-packages/h11/tests/test_receivebuffer.py new file mode 100644 index 0000000..21a3870 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_receivebuffer.py @@ -0,0 +1,135 @@ +import re +from typing import Tuple + +import pytest + +from .._receivebuffer import ReceiveBuffer + + +def test_receivebuffer() -> None: + b = ReceiveBuffer() + assert not b + assert len(b) == 0 + assert bytes(b) == b"" + + b += b"123" + assert b + assert len(b) == 3 + assert bytes(b) == b"123" + + assert bytes(b) == b"123" + + assert b.maybe_extract_at_most(2) == b"12" + assert b + assert len(b) == 1 + assert bytes(b) == b"3" + + assert bytes(b) == b"3" + + assert b.maybe_extract_at_most(10) == b"3" + assert bytes(b) == b"" + + assert b.maybe_extract_at_most(10) is None + assert not b + + ################################################################ + # maybe_extract_until_next + ################################################################ + + b += b"123\n456\r\n789\r\n" + + assert b.maybe_extract_next_line() == b"123\n456\r\n" + assert bytes(b) == b"789\r\n" + + assert b.maybe_extract_next_line() == b"789\r\n" + assert bytes(b) == b"" + + b += b"12\r" + assert b.maybe_extract_next_line() is None + assert bytes(b) == b"12\r" + + b += b"345\n\r" + assert b.maybe_extract_next_line() is None + assert bytes(b) == b"12\r345\n\r" + + # here we stopped at the middle of b"\r\n" delimiter + + b += b"\n6789aaa123\r\n" + assert b.maybe_extract_next_line() == b"12\r345\n\r\n" + assert b.maybe_extract_next_line() == b"6789aaa123\r\n" + assert b.maybe_extract_next_line() is None + assert bytes(b) == b"" + + ################################################################ + # maybe_extract_lines + ################################################################ + + b += b"123\r\na: b\r\nfoo:bar\r\n\r\ntrailing" + lines = b.maybe_extract_lines() + assert lines == [b"123", b"a: b", b"foo:bar"] + assert bytes(b) == b"trailing" + + assert b.maybe_extract_lines() is None + + b += b"\r\n\r" + assert b.maybe_extract_lines() is None + + assert b.maybe_extract_at_most(100) == b"trailing\r\n\r" + assert not b + + # Empty body case (as happens at the end of chunked encoding if there are + # no trailing headers, e.g.) + b += b"\r\ntrailing" + assert b.maybe_extract_lines() == [] + assert bytes(b) == b"trailing" + + +@pytest.mark.parametrize( + "data", + [ + pytest.param( + ( + b"HTTP/1.1 200 OK\r\n", + b"Content-type: text/plain\r\n", + b"Connection: close\r\n", + b"\r\n", + b"Some body", + ), + id="with_crlf_delimiter", + ), + pytest.param( + ( + b"HTTP/1.1 200 OK\n", + b"Content-type: text/plain\n", + b"Connection: close\n", + b"\n", + b"Some body", + ), + id="with_lf_only_delimiter", + ), + pytest.param( + ( + b"HTTP/1.1 200 OK\n", + b"Content-type: text/plain\r\n", + b"Connection: close\n", + b"\n", + b"Some body", + ), + id="with_mixed_crlf_and_lf", + ), + ], +) +def test_receivebuffer_for_invalid_delimiter(data: Tuple[bytes]) -> None: + b = ReceiveBuffer() + + for line in data: + b += line + + lines = b.maybe_extract_lines() + + assert lines == [ + b"HTTP/1.1 200 OK", + b"Content-type: text/plain", + b"Connection: close", + ] + assert bytes(b) == b"Some body" diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_state.py b/venv/lib/python3.11/site-packages/h11/tests/test_state.py new file mode 100644 index 0000000..bc974e6 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_state.py @@ -0,0 +1,271 @@ +import pytest + +from .._events import ( + ConnectionClosed, + Data, + EndOfMessage, + Event, + InformationalResponse, + Request, + Response, +) +from .._state import ( + _SWITCH_CONNECT, + _SWITCH_UPGRADE, + CLIENT, + CLOSED, + ConnectionState, + DONE, + IDLE, + MIGHT_SWITCH_PROTOCOL, + MUST_CLOSE, + SEND_BODY, + SEND_RESPONSE, + SERVER, + SWITCHED_PROTOCOL, +) +from .._util import LocalProtocolError + + +def test_ConnectionState() -> None: + cs = ConnectionState() + + # Basic event-triggered transitions + + assert cs.states == {CLIENT: IDLE, SERVER: IDLE} + + cs.process_event(CLIENT, Request) + # The SERVER-Request special case: + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + # Illegal transitions raise an error and nothing happens + with pytest.raises(LocalProtocolError): + cs.process_event(CLIENT, Request) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, InformationalResponse) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, Response) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_BODY} + + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, EndOfMessage) + assert cs.states == {CLIENT: DONE, SERVER: DONE} + + # State-triggered transition + + cs.process_event(SERVER, ConnectionClosed) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: CLOSED} + + +def test_ConnectionState_keep_alive() -> None: + # keep_alive = False + cs = ConnectionState() + cs.process_event(CLIENT, Request) + cs.process_keep_alive_disabled() + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: MUST_CLOSE} + + +def test_ConnectionState_keep_alive_in_DONE() -> None: + # Check that if keep_alive is disabled when the CLIENT is already in DONE, + # then this is sufficient to immediately trigger the DONE -> MUST_CLOSE + # transition + cs = ConnectionState() + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + assert cs.states[CLIENT] is DONE + cs.process_keep_alive_disabled() + assert cs.states[CLIENT] is MUST_CLOSE + + +def test_ConnectionState_switch_denied() -> None: + for switch_type in (_SWITCH_CONNECT, _SWITCH_UPGRADE): + for deny_early in (True, False): + cs = ConnectionState() + cs.process_client_switch_proposal(switch_type) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, Data) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + assert switch_type in cs.pending_switch_proposals + + if deny_early: + # before client reaches DONE + cs.process_event(SERVER, Response) + assert not cs.pending_switch_proposals + + cs.process_event(CLIENT, EndOfMessage) + + if deny_early: + assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} + else: + assert cs.states == { + CLIENT: MIGHT_SWITCH_PROTOCOL, + SERVER: SEND_RESPONSE, + } + + cs.process_event(SERVER, InformationalResponse) + assert cs.states == { + CLIENT: MIGHT_SWITCH_PROTOCOL, + SERVER: SEND_RESPONSE, + } + + cs.process_event(SERVER, Response) + assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} + assert not cs.pending_switch_proposals + + +_response_type_for_switch = { + _SWITCH_UPGRADE: InformationalResponse, + _SWITCH_CONNECT: Response, + None: Response, +} + + +def test_ConnectionState_protocol_switch_accepted() -> None: + for switch_event in [_SWITCH_UPGRADE, _SWITCH_CONNECT]: + cs = ConnectionState() + cs.process_client_switch_proposal(switch_event) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, Data) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, InformationalResponse) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + + cs.process_event(SERVER, _response_type_for_switch[switch_event], switch_event) + assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} + + +def test_ConnectionState_double_protocol_switch() -> None: + # CONNECT + Upgrade is legal! Very silly, but legal. So we support + # it. Because sometimes doing the silly thing is easier than not. + for server_switch in [None, _SWITCH_UPGRADE, _SWITCH_CONNECT]: + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_client_switch_proposal(_SWITCH_CONNECT) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + cs.process_event( + SERVER, _response_type_for_switch[server_switch], server_switch + ) + if server_switch is None: + assert cs.states == {CLIENT: DONE, SERVER: SEND_BODY} + else: + assert cs.states == {CLIENT: SWITCHED_PROTOCOL, SERVER: SWITCHED_PROTOCOL} + + +def test_ConnectionState_inconsistent_protocol_switch() -> None: + for client_switches, server_switch in [ + ([], _SWITCH_CONNECT), + ([], _SWITCH_UPGRADE), + ([_SWITCH_UPGRADE], _SWITCH_CONNECT), + ([_SWITCH_CONNECT], _SWITCH_UPGRADE), + ]: + cs = ConnectionState() + for client_switch in client_switches: # type: ignore[attr-defined] + cs.process_client_switch_proposal(client_switch) + cs.process_event(CLIENT, Request) + with pytest.raises(LocalProtocolError): + cs.process_event(SERVER, Response, server_switch) + + +def test_ConnectionState_keepalive_protocol_switch_interaction() -> None: + # keep_alive=False + pending_switch_proposals + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_event(CLIENT, Request) + cs.process_keep_alive_disabled() + cs.process_event(CLIENT, Data) + assert cs.states == {CLIENT: SEND_BODY, SERVER: SEND_RESPONSE} + + # the protocol switch "wins" + cs.process_event(CLIENT, EndOfMessage) + assert cs.states == {CLIENT: MIGHT_SWITCH_PROTOCOL, SERVER: SEND_RESPONSE} + + # but when the server denies the request, keep_alive comes back into play + cs.process_event(SERVER, Response) + assert cs.states == {CLIENT: MUST_CLOSE, SERVER: SEND_BODY} + + +def test_ConnectionState_reuse() -> None: + cs = ConnectionState() + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + cs.start_next_cycle() + assert cs.states == {CLIENT: IDLE, SERVER: IDLE} + + # No keepalive + + cs.process_event(CLIENT, Request) + cs.process_keep_alive_disabled() + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + # One side closed + + cs = ConnectionState() + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(CLIENT, ConnectionClosed) + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + # Succesful protocol switch + + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, InformationalResponse, _SWITCH_UPGRADE) + + with pytest.raises(LocalProtocolError): + cs.start_next_cycle() + + # Failed protocol switch + + cs = ConnectionState() + cs.process_client_switch_proposal(_SWITCH_UPGRADE) + cs.process_event(CLIENT, Request) + cs.process_event(CLIENT, EndOfMessage) + cs.process_event(SERVER, Response) + cs.process_event(SERVER, EndOfMessage) + + cs.start_next_cycle() + assert cs.states == {CLIENT: IDLE, SERVER: IDLE} + + +def test_server_request_is_illegal() -> None: + # There used to be a bug in how we handled the Request special case that + # made this allowed... + cs = ConnectionState() + with pytest.raises(LocalProtocolError): + cs.process_event(SERVER, Request) diff --git a/venv/lib/python3.11/site-packages/h11/tests/test_util.py b/venv/lib/python3.11/site-packages/h11/tests/test_util.py new file mode 100644 index 0000000..79bc095 --- /dev/null +++ b/venv/lib/python3.11/site-packages/h11/tests/test_util.py @@ -0,0 +1,112 @@ +import re +import sys +import traceback +from typing import NoReturn + +import pytest + +from .._util import ( + bytesify, + LocalProtocolError, + ProtocolError, + RemoteProtocolError, + Sentinel, + validate, +) + + +def test_ProtocolError() -> None: + with pytest.raises(TypeError): + ProtocolError("abstract base class") + + +def test_LocalProtocolError() -> None: + try: + raise LocalProtocolError("foo") + except LocalProtocolError as e: + assert str(e) == "foo" + assert e.error_status_hint == 400 + + try: + raise LocalProtocolError("foo", error_status_hint=418) + except LocalProtocolError as e: + assert str(e) == "foo" + assert e.error_status_hint == 418 + + def thunk() -> NoReturn: + raise LocalProtocolError("a", error_status_hint=420) + + try: + try: + thunk() + except LocalProtocolError as exc1: + orig_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) + exc1._reraise_as_remote_protocol_error() + except RemoteProtocolError as exc2: + assert type(exc2) is RemoteProtocolError + assert exc2.args == ("a",) + assert exc2.error_status_hint == 420 + new_traceback = "".join(traceback.format_tb(sys.exc_info()[2])) + assert new_traceback.endswith(orig_traceback) + + +def test_validate() -> None: + my_re = re.compile(rb"(?P[0-9]+)\.(?P[0-9]+)") + with pytest.raises(LocalProtocolError): + validate(my_re, b"0.") + + groups = validate(my_re, b"0.1") + assert groups == {"group1": b"0", "group2": b"1"} + + # successful partial matches are an error - must match whole string + with pytest.raises(LocalProtocolError): + validate(my_re, b"0.1xx") + with pytest.raises(LocalProtocolError): + validate(my_re, b"0.1\n") + + +def test_validate_formatting() -> None: + my_re = re.compile(rb"foo") + + with pytest.raises(LocalProtocolError) as excinfo: + validate(my_re, b"", "oops") + assert "oops" in str(excinfo.value) + + with pytest.raises(LocalProtocolError) as excinfo: + validate(my_re, b"", "oops {}") + assert "oops {}" in str(excinfo.value) + + with pytest.raises(LocalProtocolError) as excinfo: + validate(my_re, b"", "oops {} xx", 10) + assert "oops 10 xx" in str(excinfo.value) + + +def test_make_sentinel() -> None: + class S(Sentinel, metaclass=Sentinel): + pass + + assert repr(S) == "S" + assert S == S + assert type(S).__name__ == "S" + assert S in {S} + assert type(S) is S + + class S2(Sentinel, metaclass=Sentinel): + pass + + assert repr(S2) == "S2" + assert S != S2 + assert S not in {S2} + assert type(S) is not type(S2) + + +def test_bytesify() -> None: + assert bytesify(b"123") == b"123" + assert bytesify(bytearray(b"123")) == b"123" + assert bytesify("123") == b"123" + + with pytest.raises(UnicodeEncodeError): + bytesify("\u1234") + + with pytest.raises(TypeError): + bytesify(10) diff --git a/venv/lib/python3.11/site-packages/idna-3.10.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/idna-3.10.dist-info/LICENSE.md b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/LICENSE.md new file mode 100644 index 0000000..19b6b45 --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/LICENSE.md @@ -0,0 +1,31 @@ +BSD 3-Clause License + +Copyright (c) 2013-2024, Kim Davies and contributors. +All rights reserved. + +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.11/site-packages/idna-3.10.dist-info/METADATA b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/METADATA new file mode 100644 index 0000000..c42623e --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/METADATA @@ -0,0 +1,250 @@ +Metadata-Version: 2.1 +Name: idna +Version: 3.10 +Summary: Internationalized Domain Names in Applications (IDNA) +Author-email: Kim Davies +Requires-Python: >=3.6 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.6 +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 :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Requires-Dist: ruff >= 0.6.2 ; extra == "all" +Requires-Dist: mypy >= 1.11.2 ; extra == "all" +Requires-Dist: pytest >= 8.3.2 ; extra == "all" +Requires-Dist: flake8 >= 7.1.1 ; extra == "all" +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.rst +Project-URL: Issue tracker, https://github.com/kjd/idna/issues +Project-URL: Source, https://github.com/kjd/idna +Provides-Extra: all + +Internationalized Domain Names in Applications (IDNA) +===================================================== + +Support for the Internationalized Domain Names in +Applications (IDNA) protocol as specified in `RFC 5891 +`_. This is the latest version of +the protocol and is sometimes referred to as “IDNA 2008”. + +This library also provides support for Unicode Technical +Standard 46, `Unicode IDNA Compatibility Processing +`_. + +This acts as a suitable replacement for the “encodings.idna” +module that comes with the Python standard library, but which +only supports the older superseded IDNA specification (`RFC 3490 +`_). + +Basic functions are simply executed: + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + + +Installation +------------ + +This package is available for installation from PyPI: + +.. code-block:: bash + + $ python3 -m pip install idna + + +Usage +----- + +For typical usage, the ``encode`` and ``decode`` functions will take a +domain name argument and perform a conversion to A-labels or U-labels +respectively. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + +You may use the codec encoding and decoding methods using the +``idna.codec`` module: + +.. code-block:: pycon + + >>> import idna.codec + >>> print('домен.испытание'.encode('idna2008')) + b'xn--d1acufc.xn--80akhbyknj4f' + >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna2008')) + домен.испытание + +Conversions can be applied at a per-label basis using the ``ulabel`` or +``alabel`` functions if necessary: + +.. code-block:: pycon + + >>> idna.alabel('测试') + b'xn--0zwm56d' + +Compatibility Mapping (UTS #46) ++++++++++++++++++++++++++++++++ + +As described in `RFC 5895 `_, the +IDNA specification does not normalize input from different potential +ways a user may input a domain name. This functionality, known as +a “mapping”, is considered by the specification to be a local +user-interface issue distinct from IDNA conversion functionality. + +This library provides one such mapping that was developed by the +Unicode Consortium. Known as `Unicode IDNA Compatibility Processing +`_, it provides for both a regular +mapping for typical applications, as well as a transitional mapping to +help migrate from older IDNA 2003 applications. Strings are +preprocessed according to Section 4.4 “Preprocessing for IDNA2008” +prior to the IDNA operations. + +For example, “Königsgäßchen” is not a permissible label as *LATIN +CAPITAL LETTER K* is not allowed (nor are capital letters in general). +UTS 46 will convert this into lower case prior to applying the IDNA +conversion. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('Königsgäßchen') + ... + idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed + >>> idna.encode('Königsgäßchen', uts46=True) + b'xn--knigsgchen-b4a3dun' + >>> print(idna.decode('xn--knigsgchen-b4a3dun')) + königsgäßchen + +Transitional processing provides conversions to help transition from +the older 2003 standard to the current standard. For example, in the +original IDNA specification, the *LATIN SMALL LETTER SHARP S* (ß) was +converted into two *LATIN SMALL LETTER S* (ss), whereas in the current +IDNA specification this conversion is not performed. + +.. code-block:: pycon + + >>> idna.encode('Königsgäßchen', uts46=True, transitional=True) + 'xn--knigsgsschen-lcb0w' + +Implementers should use transitional processing with caution, only in +rare cases where conversion from legacy labels to current labels must be +performed (i.e. IDNA implementations that pre-date 2008). For typical +applications that just need to convert labels, transitional processing +is unlikely to be beneficial and could produce unexpected incompatible +results. + +``encodings.idna`` Compatibility +++++++++++++++++++++++++++++++++ + +Function calls from the Python built-in ``encodings.idna`` module are +mapped to their IDNA 2008 equivalents using the ``idna.compat`` module. +Simply substitute the ``import`` clause in your code to refer to the new +module name. + +Exceptions +---------- + +All errors raised during the conversion following the specification +should raise an exception derived from the ``idna.IDNAError`` base +class. + +More specific exceptions that may be generated as ``idna.IDNABidiError`` +when the error reflects an illegal combination of left-to-right and +right-to-left characters in a label; ``idna.InvalidCodepoint`` when +a specific codepoint is an illegal character in an IDN label (i.e. +INVALID); and ``idna.InvalidCodepointContext`` when the codepoint is +illegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ +but the contextual requirements are not satisfied.) + +Building and Diagnostics +------------------------ + +The IDNA and UTS 46 functionality relies upon pre-calculated lookup +tables for performance. These tables are derived from computing against +eligibility criteria in the respective standards. These tables are +computed using the command-line script ``tools/idna-data``. + +This tool will fetch relevant codepoint data from the Unicode repository +and perform the required calculations to identify eligibility. There are +three main modes: + +* ``idna-data make-libdata``. Generates ``idnadata.py`` and + ``uts46data.py``, the pre-calculated lookup tables used for IDNA and + UTS 46 conversions. Implementers who wish to track this library against + a different Unicode version may use this tool to manually generate a + different version of the ``idnadata.py`` and ``uts46data.py`` files. + +* ``idna-data make-table``. Generate a table of the IDNA disposition + (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix + B.1 of RFC 5892 and the pre-computed tables published by `IANA + `_. + +* ``idna-data U+0061``. Prints debugging output on the various + properties associated with an individual Unicode codepoint (in this + case, U+0061), that are used to assess the IDNA and UTS 46 status of a + codepoint. This is helpful in debugging or analysis. + +The tool accepts a number of arguments, described using ``idna-data +-h``. Most notably, the ``--version`` argument allows the specification +of the version of Unicode to be used in computing the table data. For +example, ``idna-data --version 9.0.0 make-libdata`` will generate +library data against Unicode 9.0.0. + + +Additional Notes +---------------- + +* **Packages**. The latest tagged release version is published in the + `Python Package Index `_. + +* **Version support**. This library supports Python 3.6 and higher. + As this library serves as a low-level toolkit for a variety of + applications, many of which strive for broad compatibility with older + Python versions, there is no rush to remove older interpreter support. + Removing support for older versions should be well justified in that the + maintenance burden has become too high. + +* **Python 2**. Python 2 is supported by version 2.x of this library. + Use "idna<3" in your requirements file if you need this library for + a Python 2 application. Be advised that these versions are no longer + actively developed. + +* **Testing**. The library has a test suite based on each rule of the + IDNA specification, as well as tests that are provided as part of the + Unicode Technical Standard 46, `Unicode IDNA Compatibility Processing + `_. + +* **Emoji**. It is an occasional request to support emoji domains in + this library. Encoding of symbols like emoji is expressly prohibited by + the technical standard IDNA 2008 and emoji domains are broadly phased + out across the domain industry due to associated security risks. For + now, applications that need to support these non-compliant labels + may wish to consider trying the encode/decode operation in this library + first, and then falling back to using `encodings.idna`. See `the Github + project `_ for more discussion. + diff --git a/venv/lib/python3.11/site-packages/idna-3.10.dist-info/RECORD b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/RECORD new file mode 100644 index 0000000..4a47b68 --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/RECORD @@ -0,0 +1,22 @@ +idna-3.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +idna-3.10.dist-info/LICENSE.md,sha256=pZ8LDvNjWHQQmkRhykT_enDVBpboFHZ7-vch1Mmw2w8,1541 +idna-3.10.dist-info/METADATA,sha256=URR5ZyDfQ1PCEGhkYoojqfi2Ra0tau2--lhwG4XSfjI,10158 +idna-3.10.dist-info/RECORD,, +idna-3.10.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868 +idna/__pycache__/__init__.cpython-311.pyc,, +idna/__pycache__/codec.cpython-311.pyc,, +idna/__pycache__/compat.cpython-311.pyc,, +idna/__pycache__/core.cpython-311.pyc,, +idna/__pycache__/idnadata.cpython-311.pyc,, +idna/__pycache__/intranges.cpython-311.pyc,, +idna/__pycache__/package_data.cpython-311.pyc,, +idna/__pycache__/uts46data.cpython-311.pyc,, +idna/codec.py,sha256=PEew3ItwzjW4hymbasnty2N2OXvNcgHB-JjrBuxHPYY,3422 +idna/compat.py,sha256=RzLy6QQCdl9784aFhb2EX9EKGCJjg0P3PilGdeXXcx8,316 +idna/core.py,sha256=YJYyAMnwiQEPjVC4-Fqu_p4CJ6yKKuDGmppBNQNQpFs,13239 +idna/idnadata.py,sha256=W30GcIGvtOWYwAjZj4ZjuouUutC6ffgNuyjJy7fZ-lo,78306 +idna/intranges.py,sha256=amUtkdhYcQG8Zr-CoMM_kVRacxkivC1WgxN1b63KKdU,1898 +idna/package_data.py,sha256=q59S3OXsc5VI8j6vSD0sGBMyk6zZ4vWFREE88yCJYKs,21 +idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +idna/uts46data.py,sha256=rt90K9J40gUSwppDPCrhjgi5AA6pWM65dEGRSf6rIhM,239289 diff --git a/venv/lib/python3.11/site-packages/idna-3.10.dist-info/WHEEL b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna-3.10.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.11/site-packages/idna/__init__.py b/venv/lib/python3.11/site-packages/idna/__init__.py new file mode 100644 index 0000000..cfdc030 --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/__init__.py @@ -0,0 +1,45 @@ +from .core import ( + IDNABidiError, + IDNAError, + InvalidCodepoint, + InvalidCodepointContext, + alabel, + check_bidi, + check_hyphen_ok, + check_initial_combiner, + check_label, + check_nfc, + decode, + encode, + ulabel, + uts46_remap, + valid_contextj, + valid_contexto, + valid_label_length, + valid_string_length, +) +from .intranges import intranges_contain +from .package_data import __version__ + +__all__ = [ + "__version__", + "IDNABidiError", + "IDNAError", + "InvalidCodepoint", + "InvalidCodepointContext", + "alabel", + "check_bidi", + "check_hyphen_ok", + "check_initial_combiner", + "check_label", + "check_nfc", + "decode", + "encode", + "intranges_contain", + "ulabel", + "uts46_remap", + "valid_contextj", + "valid_contexto", + "valid_label_length", + "valid_string_length", +] diff --git a/venv/lib/python3.11/site-packages/idna/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/idna/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a303ad545962cebb7b8cdab02fdff2aea133f2d6 GIT binary patch literal 1090 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 u^;U2fC+5J5hiGMZ?MU&p}%$BBiA zjbL$IQd%j&#?F7^gcPzM2!ar74z5e(n>|lr2qF$M?_+*%-n{v}c{e>>CO95_|FOM7 z3Hhd+$uNEyqb)S{2qTP!B%)0kX-$n1rZGL#Bco|VX46F90E?MW*fN;)(r6aZ*PsBU zEp2v^ksxj%UO>Feia?pkO6Zr-udq^sIF%z6>u8z27WXo9GY)usgoUXsi$R++$SjC+ zZH9ge!pssNcSYP*QInygq1MPou}9=}8B-uvG>4RSy|hl&D59#Bz4l`7Cae&BX| z;dZ-S7b5;RfDR9LCD!A1Anv$f&~lTW+~M)k{NkdU1`=*2e*1~P4XGQj*mv7JN_;t= z^s>SRUu)d0*Tp$ZY~dOy<2m_Kndx7DwfcH>U|bpD4*CB_hzcIZXQ=FA3dQ&lVj9h? zw84={MVh#XzG}HRufzp~($xFcdl~(cycg8byr*;Zd)}ITYhmHG%{ZiX%%zP?g+U5- z>_?CYNbE##$=f`1Xjb*OtVc-*5yTSMeIdBO(yLg^$*PN!v*I!$im`MC1=3co4X!=> zR9-(UuMdp%{1whrX31U>#M?qOUZ~HT8Er0LOo?i5rl(S5W~(P5&0CR`lw n5u5wVZ=Au^8;6(Xa{NQ}bePI8#8{8^b%l9!-x%w^%bcm77kuC+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/idna/__pycache__/core.cpython-311.pyc b/venv/lib/python3.11/site-packages/idna/__pycache__/core.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff018bb4890ef012f7c5ec7697f4c8de443b21bd GIT binary patch literal 19259 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/idna/__pycache__/idnadata.cpython-311.pyc b/venv/lib/python3.11/site-packages/idna/__pycache__/idnadata.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f903b97da652b5bab66c508a74b519635814d6ca GIT binary patch literal 101531 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

    JV87+M$+ z#ug@osf8I~ZegKtwpq6}T(Wv)VNKXr*b?q6>NDz`1QiQaH3?XYFr*O7ec^ej3U9?alTv{j-Di*4QD+@Kk zwS_vNVWCNAS!feF7P^ER3q3;L!hkTeFd~dCObAm8Gs4`$f^chLNmyA}E1YfC#)ex~ z-&xoZ?k(&I2Mb5SgM|~pm$maI%XwqLPY75D5-u!+2w@8mLexTx5Vw#ZBrT)}X$u)b z)ENlsP7Iq3}n{{u)J*y8Ej)VsbCxS0$=S`0D#)6*^ zun;6%SO^iq79xbGg%}}jAwfu5NDNB7`kO2vG|$Lfk@vkhG8@q%C9! zSqnKr-a>&;v``{kS|}4L7OI3R3pK*Eg}TDoW;JZsWOd6zo6xb)CEQr(5&9MegrS8I zVQgVSm|B<-<`x!&TMJ9V%EFqkv9KlFS=bToE$j&g3rE6(g%iP7uydv0ohxUX^~{ET z4POK-1PK=wLWHn|2q9`AMu=NT5Rw*BgtUbWA!{K=$Xh57iWW+QOABQ}#X^;EWuZp6 zwooTDEHnu%3vGq7&Fa{&%jz2oJwo5YfH1T$B8)9e2vZ9)!ra1waBE>nSXo#THWs#o zI}1C)y@fsDVBtu3uy7*yigw-<`EQH`KOtZtsBpGf7d8yBI&2|Ah+2pd;uaEwq=ghA zZ6QO*TF4Rd77B!-g%aV?LYYvpP$gVhs1dF$)Cmm>O+w2;o6xb)CEQr(DV%Lq--ZKL z4=s!cV+#|))WVD~x3D1GT38ZR7S@D~g)QOE!j5onVNW<%I1(N#oCv;>oi`=U8w-9y zz(SC4VIf2aTZkx}ZC2EVF;>SdBnU|hDMH#phLE+8Bjha<2t^Ae!li{Wp<tc4sQZ=paaS||}NEtClr3su6Eg&N`7LY>gC&?K}hvWdW61(0byui zL>OC`5T+Jpgt>(U;nu>Eu(GfwY%FXQ&Nl1LhC5c@Ti6p07LJ4m3nzlFYUfRr^TvXo z5U>y=Tv!MZ!WJTgsD&6IZXrQPT1XMn7BYmag&ZMop+G2FC=o6#lohmD&)@Uny86=c y1Mhp=3wQCsS3dgUEib?FwilC6Jbd6o?(<_G|NP@8ul$oIued+m6-b^u`Tqd!rFjhi literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/idna/__pycache__/intranges.cpython-311.pyc b/venv/lib/python3.11/site-packages/idna/__pycache__/intranges.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dded6511d65faeb3974970c20e1a4304e3c3b48e GIT binary patch literal 2970 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%0DDn-U@WLhb7yFDNGB= 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/idna/codec.py b/venv/lib/python3.11/site-packages/idna/codec.py new file mode 100644 index 0000000..913abfd --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/codec.py @@ -0,0 +1,122 @@ +import codecs +import re +from typing import Any, Optional, Tuple + +from .core import IDNAError, alabel, decode, encode, ulabel + +_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") + + +class Codec(codecs.Codec): + def encode(self, data: str, errors: str = "strict") -> Tuple[bytes, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) + + if not data: + return b"", 0 + + return encode(data), len(data) + + def decode(self, data: bytes, errors: str = "strict") -> Tuple[str, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) + + if not data: + return "", 0 + + return decode(data), len(data) + + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[bytes, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) + + if not data: + return b"", 0 + + labels = _unicode_dots_re.split(data) + trailing_dot = b"" + if labels: + if not labels[-1]: + trailing_dot = b"." + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = b"." + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result_bytes = b".".join(result) + trailing_dot + size += len(trailing_dot) + return result_bytes, size + + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data: Any, errors: str, final: bool) -> Tuple[str, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) + + if not data: + return ("", 0) + + if not isinstance(data, str): + data = str(data, "ascii") + + labels = _unicode_dots_re.split(data) + trailing_dot = "" + if labels: + if not labels[-1]: + trailing_dot = "." + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = "." + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result_str = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result_str, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +def search_function(name: str) -> Optional[codecs.CodecInfo]: + if name != "idna2008": + return None + return codecs.CodecInfo( + name=name, + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +codecs.register(search_function) diff --git a/venv/lib/python3.11/site-packages/idna/compat.py b/venv/lib/python3.11/site-packages/idna/compat.py new file mode 100644 index 0000000..1df9f2a --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/compat.py @@ -0,0 +1,15 @@ +from typing import Any, Union + +from .core import decode, encode + + +def ToASCII(label: str) -> bytes: + return encode(label) + + +def ToUnicode(label: Union[bytes, bytearray]) -> str: + return decode(label) + + +def nameprep(s: Any) -> None: + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") diff --git a/venv/lib/python3.11/site-packages/idna/core.py b/venv/lib/python3.11/site-packages/idna/core.py new file mode 100644 index 0000000..9115f12 --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/core.py @@ -0,0 +1,437 @@ +import bisect +import re +import unicodedata +from typing import Optional, Union + +from . import idnadata +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b"xn--" +_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") + + +class IDNAError(UnicodeError): + """Base exception for all IDNA-encoding related problems""" + + pass + + +class IDNABidiError(IDNAError): + """Exception when bidirectional requirements are not satisfied""" + + pass + + +class InvalidCodepoint(IDNAError): + """Exception when a disallowed or unallocated codepoint is used""" + + pass + + +class InvalidCodepointContext(IDNAError): + """Exception when the codepoint is not valid in the context it is used""" + + pass + + +def _combining_class(cp: int) -> int: + v = unicodedata.combining(chr(cp)) + if v == 0: + if not unicodedata.name(chr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + + +def _is_script(cp: str, script: str) -> bool: + return intranges_contain(ord(cp), idnadata.scripts[script]) + + +def _punycode(s: str) -> bytes: + return s.encode("punycode") + + +def _unot(s: int) -> str: + return "U+{:04X}".format(s) + + +def valid_label_length(label: Union[bytes, str]) -> bool: + if len(label) > 63: + return False + return True + + +def valid_string_length(label: Union[bytes, str], trailing_dot: bool) -> bool: + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label: str, check_ltr: bool = False) -> bool: + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for idx, cp in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == "": + # String likely comes from a newer version of Unicode + raise IDNABidiError("Unknown directionality in label {} at position {}".format(repr(label), idx)) + if direction in ["R", "AL", "AN"]: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ["R", "AL"]: + rtl = True + elif direction == "L": + rtl = False + else: + raise IDNABidiError("First codepoint in label {} must be directionality L, R or AL".format(repr(label))) + + valid_ending = False + number_type: Optional[str] = None + for idx, cp in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if direction not in [ + "R", + "AL", + "AN", + "EN", + "ES", + "CS", + "ET", + "ON", + "BN", + "NSM", + ]: + raise IDNABidiError("Invalid direction for codepoint at position {} in a right-to-left label".format(idx)) + # Bidi rule 3 + if direction in ["R", "AL", "EN", "AN"]: + valid_ending = True + elif direction != "NSM": + valid_ending = False + # Bidi rule 4 + if direction in ["AN", "EN"]: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError("Can not mix numeral types in a right-to-left label") + else: + # Bidi rule 5 + if direction not in ["L", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"]: + raise IDNABidiError("Invalid direction for codepoint at position {} in a left-to-right label".format(idx)) + # Bidi rule 6 + if direction in ["L", "EN"]: + valid_ending = True + elif direction != "NSM": + valid_ending = False + + if not valid_ending: + raise IDNABidiError("Label ends with illegal codepoint directionality") + + return True + + +def check_initial_combiner(label: str) -> bool: + if unicodedata.category(label[0])[0] == "M": + raise IDNAError("Label begins with an illegal combining character") + return True + + +def check_hyphen_ok(label: str) -> bool: + if label[2:4] == "--": + raise IDNAError("Label has disallowed hyphens in 3rd and 4th position") + if label[0] == "-" or label[-1] == "-": + raise IDNAError("Label must not start or end with a hyphen") + return True + + +def check_nfc(label: str) -> None: + if unicodedata.normalize("NFC", label) != label: + raise IDNAError("Label must be in Normalization Form C") + + +def valid_contextj(label: str, pos: int) -> bool: + cp_value = ord(label[pos]) + + if cp_value == 0x200C: + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos - 1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord("T"): + continue + elif joining_type in [ord("L"), ord("D")]: + ok = True + break + else: + break + + if not ok: + return False + + ok = False + for i in range(pos + 1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord("T"): + continue + elif joining_type in [ord("R"), ord("D")]: + ok = True + break + else: + break + return ok + + if cp_value == 0x200D: + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + return False + + +def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: + cp_value = ord(label[pos]) + + if cp_value == 0x00B7: + if 0 < pos < len(label) - 1: + if ord(label[pos - 1]) == 0x006C and ord(label[pos + 1]) == 0x006C: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label) - 1 and len(label) > 1: + return _is_script(label[pos + 1], "Greek") + return False + + elif cp_value == 0x05F3 or cp_value == 0x05F4: + if pos > 0: + return _is_script(label[pos - 1], "Hebrew") + return False + + elif cp_value == 0x30FB: + for cp in label: + if cp == "\u30fb": + continue + if _is_script(cp, "Hiragana") or _is_script(cp, "Katakana") or _is_script(cp, "Han"): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6F0 <= ord(cp) <= 0x06F9: + return False + return True + + elif 0x6F0 <= cp_value <= 0x6F9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + return False + + +def check_label(label: Union[str, bytes, bytearray]) -> None: + if isinstance(label, (bytes, bytearray)): + label = label.decode("utf-8") + if len(label) == 0: + raise IDNAError("Empty Label") + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for pos, cp in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes["PVALID"]): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext( + "Joiner {} not allowed at position {} in {}".format(_unot(cp_value), pos + 1, repr(label)) + ) + except ValueError: + raise IDNAError( + "Unknown codepoint adjacent to joiner {} at position {} in {}".format( + _unot(cp_value), pos + 1, repr(label) + ) + ) + elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]): + if not valid_contexto(label, pos): + raise InvalidCodepointContext( + "Codepoint {} not allowed at position {} in {}".format(_unot(cp_value), pos + 1, repr(label)) + ) + else: + raise InvalidCodepoint( + "Codepoint {} at position {} of {} not allowed".format(_unot(cp_value), pos + 1, repr(label)) + ) + + check_bidi(label) + + +def alabel(label: str) -> bytes: + try: + label_bytes = label.encode("ascii") + ulabel(label_bytes) + if not valid_label_length(label_bytes): + raise IDNAError("Label too long") + return label_bytes + except UnicodeEncodeError: + pass + + check_label(label) + label_bytes = _alabel_prefix + _punycode(label) + + if not valid_label_length(label_bytes): + raise IDNAError("Label too long") + + return label_bytes + + +def ulabel(label: Union[str, bytes, bytearray]) -> str: + if not isinstance(label, (bytes, bytearray)): + try: + label_bytes = label.encode("ascii") + except UnicodeEncodeError: + check_label(label) + return label + else: + label_bytes = label + + label_bytes = label_bytes.lower() + if label_bytes.startswith(_alabel_prefix): + label_bytes = label_bytes[len(_alabel_prefix) :] + if not label_bytes: + raise IDNAError("Malformed A-label, no Punycode eligible content found") + if label_bytes.decode("ascii")[-1] == "-": + raise IDNAError("A-label must not end with a hyphen") + else: + check_label(label_bytes) + return label_bytes.decode("ascii") + + try: + label = label_bytes.decode("punycode") + except UnicodeError: + raise IDNAError("Invalid A-label") + check_label(label) + return label + + +def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + + output = "" + + for pos, char in enumerate(domain): + code_point = ord(char) + try: + uts46row = uts46data[code_point if code_point < 256 else bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement: Optional[str] = None + if len(uts46row) == 3: + replacement = uts46row[2] + if ( + status == "V" + or (status == "D" and not transitional) + or (status == "3" and not std3_rules and replacement is None) + ): + output += char + elif replacement is not None and ( + status == "M" or (status == "3" and not std3_rules) or (status == "D" and transitional) + ): + output += replacement + elif status != "I": + raise IndexError() + except IndexError: + raise InvalidCodepoint( + "Codepoint {} not allowed at position {} in {}".format(_unot(code_point), pos + 1, repr(domain)) + ) + + return unicodedata.normalize("NFC", output) + + +def encode( + s: Union[str, bytes, bytearray], + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, + transitional: bool = False, +) -> bytes: + if not isinstance(s, str): + try: + s = str(s, "ascii") + except UnicodeDecodeError: + raise IDNAError("should pass a unicode string to the function rather than a byte string.") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split(".") + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == [""]: + raise IDNAError("Empty domain") + if labels[-1] == "": + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError("Empty label") + if trailing_dot: + result.append(b"") + s = b".".join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError("Domain too long") + return s + + +def decode( + s: Union[str, bytes, bytearray], + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, +) -> str: + try: + if not isinstance(s, str): + s = str(s, "ascii") + except UnicodeDecodeError: + raise IDNAError("Invalid ASCII in A-label") + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split(".") + if not labels or labels == [""]: + raise IDNAError("Empty domain") + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError("Empty label") + if trailing_dot: + result.append("") + return ".".join(result) diff --git a/venv/lib/python3.11/site-packages/idna/idnadata.py b/venv/lib/python3.11/site-packages/idna/idnadata.py new file mode 100644 index 0000000..4be6004 --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/idnadata.py @@ -0,0 +1,4243 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "15.1.0" +scripts = { + "Greek": ( + 0x37000000374, + 0x37500000378, + 0x37A0000037E, + 0x37F00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038B, + 0x38C0000038D, + 0x38E000003A2, + 0x3A3000003E2, + 0x3F000000400, + 0x1D2600001D2B, + 0x1D5D00001D62, + 0x1D6600001D6B, + 0x1DBF00001DC0, + 0x1F0000001F16, + 0x1F1800001F1E, + 0x1F2000001F46, + 0x1F4800001F4E, + 0x1F5000001F58, + 0x1F5900001F5A, + 0x1F5B00001F5C, + 0x1F5D00001F5E, + 0x1F5F00001F7E, + 0x1F8000001FB5, + 0x1FB600001FC5, + 0x1FC600001FD4, + 0x1FD600001FDC, + 0x1FDD00001FF0, + 0x1FF200001FF5, + 0x1FF600001FFF, + 0x212600002127, + 0xAB650000AB66, + 0x101400001018F, + 0x101A0000101A1, + 0x1D2000001D246, + ), + "Han": ( + 0x2E8000002E9A, + 0x2E9B00002EF4, + 0x2F0000002FD6, + 0x300500003006, + 0x300700003008, + 0x30210000302A, + 0x30380000303C, + 0x340000004DC0, + 0x4E000000A000, + 0xF9000000FA6E, + 0xFA700000FADA, + 0x16FE200016FE4, + 0x16FF000016FF2, + 0x200000002A6E0, + 0x2A7000002B73A, + 0x2B7400002B81E, + 0x2B8200002CEA2, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x2F8000002FA1E, + 0x300000003134B, + 0x31350000323B0, + ), + "Hebrew": ( + 0x591000005C8, + 0x5D0000005EB, + 0x5EF000005F5, + 0xFB1D0000FB37, + 0xFB380000FB3D, + 0xFB3E0000FB3F, + 0xFB400000FB42, + 0xFB430000FB45, + 0xFB460000FB50, + ), + "Hiragana": ( + 0x304100003097, + 0x309D000030A0, + 0x1B0010001B120, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1F2000001F201, + ), + "Katakana": ( + 0x30A1000030FB, + 0x30FD00003100, + 0x31F000003200, + 0x32D0000032FF, + 0x330000003358, + 0xFF660000FF70, + 0xFF710000FF9E, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B001, + 0x1B1200001B123, + 0x1B1550001B156, + 0x1B1640001B168, + ), +} +joining_types = { + 0xAD: 84, + 0x300: 84, + 0x301: 84, + 0x302: 84, + 0x303: 84, + 0x304: 84, + 0x305: 84, + 0x306: 84, + 0x307: 84, + 0x308: 84, + 0x309: 84, + 0x30A: 84, + 0x30B: 84, + 0x30C: 84, + 0x30D: 84, + 0x30E: 84, + 0x30F: 84, + 0x310: 84, + 0x311: 84, + 0x312: 84, + 0x313: 84, + 0x314: 84, + 0x315: 84, + 0x316: 84, + 0x317: 84, + 0x318: 84, + 0x319: 84, + 0x31A: 84, + 0x31B: 84, + 0x31C: 84, + 0x31D: 84, + 0x31E: 84, + 0x31F: 84, + 0x320: 84, + 0x321: 84, + 0x322: 84, + 0x323: 84, + 0x324: 84, + 0x325: 84, + 0x326: 84, + 0x327: 84, + 0x328: 84, + 0x329: 84, + 0x32A: 84, + 0x32B: 84, + 0x32C: 84, + 0x32D: 84, + 0x32E: 84, + 0x32F: 84, + 0x330: 84, + 0x331: 84, + 0x332: 84, + 0x333: 84, + 0x334: 84, + 0x335: 84, + 0x336: 84, + 0x337: 84, + 0x338: 84, + 0x339: 84, + 0x33A: 84, + 0x33B: 84, + 0x33C: 84, + 0x33D: 84, + 0x33E: 84, + 0x33F: 84, + 0x340: 84, + 0x341: 84, + 0x342: 84, + 0x343: 84, + 0x344: 84, + 0x345: 84, + 0x346: 84, + 0x347: 84, + 0x348: 84, + 0x349: 84, + 0x34A: 84, + 0x34B: 84, + 0x34C: 84, + 0x34D: 84, + 0x34E: 84, + 0x34F: 84, + 0x350: 84, + 0x351: 84, + 0x352: 84, + 0x353: 84, + 0x354: 84, + 0x355: 84, + 0x356: 84, + 0x357: 84, + 0x358: 84, + 0x359: 84, + 0x35A: 84, + 0x35B: 84, + 0x35C: 84, + 0x35D: 84, + 0x35E: 84, + 0x35F: 84, + 0x360: 84, + 0x361: 84, + 0x362: 84, + 0x363: 84, + 0x364: 84, + 0x365: 84, + 0x366: 84, + 0x367: 84, + 0x368: 84, + 0x369: 84, + 0x36A: 84, + 0x36B: 84, + 0x36C: 84, + 0x36D: 84, + 0x36E: 84, + 0x36F: 84, + 0x483: 84, + 0x484: 84, + 0x485: 84, + 0x486: 84, + 0x487: 84, + 0x488: 84, + 0x489: 84, + 0x591: 84, + 0x592: 84, + 0x593: 84, + 0x594: 84, + 0x595: 84, + 0x596: 84, + 0x597: 84, + 0x598: 84, + 0x599: 84, + 0x59A: 84, + 0x59B: 84, + 0x59C: 84, + 0x59D: 84, + 0x59E: 84, + 0x59F: 84, + 0x5A0: 84, + 0x5A1: 84, + 0x5A2: 84, + 0x5A3: 84, + 0x5A4: 84, + 0x5A5: 84, + 0x5A6: 84, + 0x5A7: 84, + 0x5A8: 84, + 0x5A9: 84, + 0x5AA: 84, + 0x5AB: 84, + 0x5AC: 84, + 0x5AD: 84, + 0x5AE: 84, + 0x5AF: 84, + 0x5B0: 84, + 0x5B1: 84, + 0x5B2: 84, + 0x5B3: 84, + 0x5B4: 84, + 0x5B5: 84, + 0x5B6: 84, + 0x5B7: 84, + 0x5B8: 84, + 0x5B9: 84, + 0x5BA: 84, + 0x5BB: 84, + 0x5BC: 84, + 0x5BD: 84, + 0x5BF: 84, + 0x5C1: 84, + 0x5C2: 84, + 0x5C4: 84, + 0x5C5: 84, + 0x5C7: 84, + 0x610: 84, + 0x611: 84, + 0x612: 84, + 0x613: 84, + 0x614: 84, + 0x615: 84, + 0x616: 84, + 0x617: 84, + 0x618: 84, + 0x619: 84, + 0x61A: 84, + 0x61C: 84, + 0x620: 68, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62A: 68, + 0x62B: 68, + 0x62C: 68, + 0x62D: 68, + 0x62E: 68, + 0x62F: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63A: 68, + 0x63B: 68, + 0x63C: 68, + 0x63D: 68, + 0x63E: 68, + 0x63F: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64A: 68, + 0x64B: 84, + 0x64C: 84, + 0x64D: 84, + 0x64E: 84, + 0x64F: 84, + 0x650: 84, + 0x651: 84, + 0x652: 84, + 0x653: 84, + 0x654: 84, + 0x655: 84, + 0x656: 84, + 0x657: 84, + 0x658: 84, + 0x659: 84, + 0x65A: 84, + 0x65B: 84, + 0x65C: 84, + 0x65D: 84, + 0x65E: 84, + 0x65F: 84, + 0x66E: 68, + 0x66F: 68, + 0x670: 84, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67A: 68, + 0x67B: 68, + 0x67C: 68, + 0x67D: 68, + 0x67E: 68, + 0x67F: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68A: 82, + 0x68B: 82, + 0x68C: 82, + 0x68D: 82, + 0x68E: 82, + 0x68F: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69A: 68, + 0x69B: 68, + 0x69C: 68, + 0x69D: 68, + 0x69E: 68, + 0x69F: 68, + 0x6A0: 68, + 0x6A1: 68, + 0x6A2: 68, + 0x6A3: 68, + 0x6A4: 68, + 0x6A5: 68, + 0x6A6: 68, + 0x6A7: 68, + 0x6A8: 68, + 0x6A9: 68, + 0x6AA: 68, + 0x6AB: 68, + 0x6AC: 68, + 0x6AD: 68, + 0x6AE: 68, + 0x6AF: 68, + 0x6B0: 68, + 0x6B1: 68, + 0x6B2: 68, + 0x6B3: 68, + 0x6B4: 68, + 0x6B5: 68, + 0x6B6: 68, + 0x6B7: 68, + 0x6B8: 68, + 0x6B9: 68, + 0x6BA: 68, + 0x6BB: 68, + 0x6BC: 68, + 0x6BD: 68, + 0x6BE: 68, + 0x6BF: 68, + 0x6C0: 82, + 0x6C1: 68, + 0x6C2: 68, + 0x6C3: 82, + 0x6C4: 82, + 0x6C5: 82, + 0x6C6: 82, + 0x6C7: 82, + 0x6C8: 82, + 0x6C9: 82, + 0x6CA: 82, + 0x6CB: 82, + 0x6CC: 68, + 0x6CD: 82, + 0x6CE: 68, + 0x6CF: 82, + 0x6D0: 68, + 0x6D1: 68, + 0x6D2: 82, + 0x6D3: 82, + 0x6D5: 82, + 0x6D6: 84, + 0x6D7: 84, + 0x6D8: 84, + 0x6D9: 84, + 0x6DA: 84, + 0x6DB: 84, + 0x6DC: 84, + 0x6DF: 84, + 0x6E0: 84, + 0x6E1: 84, + 0x6E2: 84, + 0x6E3: 84, + 0x6E4: 84, + 0x6E7: 84, + 0x6E8: 84, + 0x6EA: 84, + 0x6EB: 84, + 0x6EC: 84, + 0x6ED: 84, + 0x6EE: 82, + 0x6EF: 82, + 0x6FA: 68, + 0x6FB: 68, + 0x6FC: 68, + 0x6FF: 68, + 0x70F: 84, + 0x710: 82, + 0x711: 84, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71A: 68, + 0x71B: 68, + 0x71C: 68, + 0x71D: 68, + 0x71E: 82, + 0x71F: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72A: 82, + 0x72B: 68, + 0x72C: 82, + 0x72D: 68, + 0x72E: 68, + 0x72F: 82, + 0x730: 84, + 0x731: 84, + 0x732: 84, + 0x733: 84, + 0x734: 84, + 0x735: 84, + 0x736: 84, + 0x737: 84, + 0x738: 84, + 0x739: 84, + 0x73A: 84, + 0x73B: 84, + 0x73C: 84, + 0x73D: 84, + 0x73E: 84, + 0x73F: 84, + 0x740: 84, + 0x741: 84, + 0x742: 84, + 0x743: 84, + 0x744: 84, + 0x745: 84, + 0x746: 84, + 0x747: 84, + 0x748: 84, + 0x749: 84, + 0x74A: 84, + 0x74D: 82, + 0x74E: 68, + 0x74F: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75A: 82, + 0x75B: 82, + 0x75C: 68, + 0x75D: 68, + 0x75E: 68, + 0x75F: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76A: 68, + 0x76B: 82, + 0x76C: 82, + 0x76D: 68, + 0x76E: 68, + 0x76F: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77A: 68, + 0x77B: 68, + 0x77C: 68, + 0x77D: 68, + 0x77E: 68, + 0x77F: 68, + 0x7A6: 84, + 0x7A7: 84, + 0x7A8: 84, + 0x7A9: 84, + 0x7AA: 84, + 0x7AB: 84, + 0x7AC: 84, + 0x7AD: 84, + 0x7AE: 84, + 0x7AF: 84, + 0x7B0: 84, + 0x7CA: 68, + 0x7CB: 68, + 0x7CC: 68, + 0x7CD: 68, + 0x7CE: 68, + 0x7CF: 68, + 0x7D0: 68, + 0x7D1: 68, + 0x7D2: 68, + 0x7D3: 68, + 0x7D4: 68, + 0x7D5: 68, + 0x7D6: 68, + 0x7D7: 68, + 0x7D8: 68, + 0x7D9: 68, + 0x7DA: 68, + 0x7DB: 68, + 0x7DC: 68, + 0x7DD: 68, + 0x7DE: 68, + 0x7DF: 68, + 0x7E0: 68, + 0x7E1: 68, + 0x7E2: 68, + 0x7E3: 68, + 0x7E4: 68, + 0x7E5: 68, + 0x7E6: 68, + 0x7E7: 68, + 0x7E8: 68, + 0x7E9: 68, + 0x7EA: 68, + 0x7EB: 84, + 0x7EC: 84, + 0x7ED: 84, + 0x7EE: 84, + 0x7EF: 84, + 0x7F0: 84, + 0x7F1: 84, + 0x7F2: 84, + 0x7F3: 84, + 0x7FA: 67, + 0x7FD: 84, + 0x816: 84, + 0x817: 84, + 0x818: 84, + 0x819: 84, + 0x81B: 84, + 0x81C: 84, + 0x81D: 84, + 0x81E: 84, + 0x81F: 84, + 0x820: 84, + 0x821: 84, + 0x822: 84, + 0x823: 84, + 0x825: 84, + 0x826: 84, + 0x827: 84, + 0x829: 84, + 0x82A: 84, + 0x82B: 84, + 0x82C: 84, + 0x82D: 84, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84A: 68, + 0x84B: 68, + 0x84C: 68, + 0x84D: 68, + 0x84E: 68, + 0x84F: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 82, + 0x857: 82, + 0x858: 82, + 0x859: 84, + 0x85A: 84, + 0x85B: 84, + 0x860: 68, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86A: 82, + 0x870: 82, + 0x871: 82, + 0x872: 82, + 0x873: 82, + 0x874: 82, + 0x875: 82, + 0x876: 82, + 0x877: 82, + 0x878: 82, + 0x879: 82, + 0x87A: 82, + 0x87B: 82, + 0x87C: 82, + 0x87D: 82, + 0x87E: 82, + 0x87F: 82, + 0x880: 82, + 0x881: 82, + 0x882: 82, + 0x883: 67, + 0x884: 67, + 0x885: 67, + 0x886: 68, + 0x889: 68, + 0x88A: 68, + 0x88B: 68, + 0x88C: 68, + 0x88D: 68, + 0x88E: 82, + 0x898: 84, + 0x899: 84, + 0x89A: 84, + 0x89B: 84, + 0x89C: 84, + 0x89D: 84, + 0x89E: 84, + 0x89F: 84, + 0x8A0: 68, + 0x8A1: 68, + 0x8A2: 68, + 0x8A3: 68, + 0x8A4: 68, + 0x8A5: 68, + 0x8A6: 68, + 0x8A7: 68, + 0x8A8: 68, + 0x8A9: 68, + 0x8AA: 82, + 0x8AB: 82, + 0x8AC: 82, + 0x8AE: 82, + 0x8AF: 68, + 0x8B0: 68, + 0x8B1: 82, + 0x8B2: 82, + 0x8B3: 68, + 0x8B4: 68, + 0x8B5: 68, + 0x8B6: 68, + 0x8B7: 68, + 0x8B8: 68, + 0x8B9: 82, + 0x8BA: 68, + 0x8BB: 68, + 0x8BC: 68, + 0x8BD: 68, + 0x8BE: 68, + 0x8BF: 68, + 0x8C0: 68, + 0x8C1: 68, + 0x8C2: 68, + 0x8C3: 68, + 0x8C4: 68, + 0x8C5: 68, + 0x8C6: 68, + 0x8C7: 68, + 0x8C8: 68, + 0x8CA: 84, + 0x8CB: 84, + 0x8CC: 84, + 0x8CD: 84, + 0x8CE: 84, + 0x8CF: 84, + 0x8D0: 84, + 0x8D1: 84, + 0x8D2: 84, + 0x8D3: 84, + 0x8D4: 84, + 0x8D5: 84, + 0x8D6: 84, + 0x8D7: 84, + 0x8D8: 84, + 0x8D9: 84, + 0x8DA: 84, + 0x8DB: 84, + 0x8DC: 84, + 0x8DD: 84, + 0x8DE: 84, + 0x8DF: 84, + 0x8E0: 84, + 0x8E1: 84, + 0x8E3: 84, + 0x8E4: 84, + 0x8E5: 84, + 0x8E6: 84, + 0x8E7: 84, + 0x8E8: 84, + 0x8E9: 84, + 0x8EA: 84, + 0x8EB: 84, + 0x8EC: 84, + 0x8ED: 84, + 0x8EE: 84, + 0x8EF: 84, + 0x8F0: 84, + 0x8F1: 84, + 0x8F2: 84, + 0x8F3: 84, + 0x8F4: 84, + 0x8F5: 84, + 0x8F6: 84, + 0x8F7: 84, + 0x8F8: 84, + 0x8F9: 84, + 0x8FA: 84, + 0x8FB: 84, + 0x8FC: 84, + 0x8FD: 84, + 0x8FE: 84, + 0x8FF: 84, + 0x900: 84, + 0x901: 84, + 0x902: 84, + 0x93A: 84, + 0x93C: 84, + 0x941: 84, + 0x942: 84, + 0x943: 84, + 0x944: 84, + 0x945: 84, + 0x946: 84, + 0x947: 84, + 0x948: 84, + 0x94D: 84, + 0x951: 84, + 0x952: 84, + 0x953: 84, + 0x954: 84, + 0x955: 84, + 0x956: 84, + 0x957: 84, + 0x962: 84, + 0x963: 84, + 0x981: 84, + 0x9BC: 84, + 0x9C1: 84, + 0x9C2: 84, + 0x9C3: 84, + 0x9C4: 84, + 0x9CD: 84, + 0x9E2: 84, + 0x9E3: 84, + 0x9FE: 84, + 0xA01: 84, + 0xA02: 84, + 0xA3C: 84, + 0xA41: 84, + 0xA42: 84, + 0xA47: 84, + 0xA48: 84, + 0xA4B: 84, + 0xA4C: 84, + 0xA4D: 84, + 0xA51: 84, + 0xA70: 84, + 0xA71: 84, + 0xA75: 84, + 0xA81: 84, + 0xA82: 84, + 0xABC: 84, + 0xAC1: 84, + 0xAC2: 84, + 0xAC3: 84, + 0xAC4: 84, + 0xAC5: 84, + 0xAC7: 84, + 0xAC8: 84, + 0xACD: 84, + 0xAE2: 84, + 0xAE3: 84, + 0xAFA: 84, + 0xAFB: 84, + 0xAFC: 84, + 0xAFD: 84, + 0xAFE: 84, + 0xAFF: 84, + 0xB01: 84, + 0xB3C: 84, + 0xB3F: 84, + 0xB41: 84, + 0xB42: 84, + 0xB43: 84, + 0xB44: 84, + 0xB4D: 84, + 0xB55: 84, + 0xB56: 84, + 0xB62: 84, + 0xB63: 84, + 0xB82: 84, + 0xBC0: 84, + 0xBCD: 84, + 0xC00: 84, + 0xC04: 84, + 0xC3C: 84, + 0xC3E: 84, + 0xC3F: 84, + 0xC40: 84, + 0xC46: 84, + 0xC47: 84, + 0xC48: 84, + 0xC4A: 84, + 0xC4B: 84, + 0xC4C: 84, + 0xC4D: 84, + 0xC55: 84, + 0xC56: 84, + 0xC62: 84, + 0xC63: 84, + 0xC81: 84, + 0xCBC: 84, + 0xCBF: 84, + 0xCC6: 84, + 0xCCC: 84, + 0xCCD: 84, + 0xCE2: 84, + 0xCE3: 84, + 0xD00: 84, + 0xD01: 84, + 0xD3B: 84, + 0xD3C: 84, + 0xD41: 84, + 0xD42: 84, + 0xD43: 84, + 0xD44: 84, + 0xD4D: 84, + 0xD62: 84, + 0xD63: 84, + 0xD81: 84, + 0xDCA: 84, + 0xDD2: 84, + 0xDD3: 84, + 0xDD4: 84, + 0xDD6: 84, + 0xE31: 84, + 0xE34: 84, + 0xE35: 84, + 0xE36: 84, + 0xE37: 84, + 0xE38: 84, + 0xE39: 84, + 0xE3A: 84, + 0xE47: 84, + 0xE48: 84, + 0xE49: 84, + 0xE4A: 84, + 0xE4B: 84, + 0xE4C: 84, + 0xE4D: 84, + 0xE4E: 84, + 0xEB1: 84, + 0xEB4: 84, + 0xEB5: 84, + 0xEB6: 84, + 0xEB7: 84, + 0xEB8: 84, + 0xEB9: 84, + 0xEBA: 84, + 0xEBB: 84, + 0xEBC: 84, + 0xEC8: 84, + 0xEC9: 84, + 0xECA: 84, + 0xECB: 84, + 0xECC: 84, + 0xECD: 84, + 0xECE: 84, + 0xF18: 84, + 0xF19: 84, + 0xF35: 84, + 0xF37: 84, + 0xF39: 84, + 0xF71: 84, + 0xF72: 84, + 0xF73: 84, + 0xF74: 84, + 0xF75: 84, + 0xF76: 84, + 0xF77: 84, + 0xF78: 84, + 0xF79: 84, + 0xF7A: 84, + 0xF7B: 84, + 0xF7C: 84, + 0xF7D: 84, + 0xF7E: 84, + 0xF80: 84, + 0xF81: 84, + 0xF82: 84, + 0xF83: 84, + 0xF84: 84, + 0xF86: 84, + 0xF87: 84, + 0xF8D: 84, + 0xF8E: 84, + 0xF8F: 84, + 0xF90: 84, + 0xF91: 84, + 0xF92: 84, + 0xF93: 84, + 0xF94: 84, + 0xF95: 84, + 0xF96: 84, + 0xF97: 84, + 0xF99: 84, + 0xF9A: 84, + 0xF9B: 84, + 0xF9C: 84, + 0xF9D: 84, + 0xF9E: 84, + 0xF9F: 84, + 0xFA0: 84, + 0xFA1: 84, + 0xFA2: 84, + 0xFA3: 84, + 0xFA4: 84, + 0xFA5: 84, + 0xFA6: 84, + 0xFA7: 84, + 0xFA8: 84, + 0xFA9: 84, + 0xFAA: 84, + 0xFAB: 84, + 0xFAC: 84, + 0xFAD: 84, + 0xFAE: 84, + 0xFAF: 84, + 0xFB0: 84, + 0xFB1: 84, + 0xFB2: 84, + 0xFB3: 84, + 0xFB4: 84, + 0xFB5: 84, + 0xFB6: 84, + 0xFB7: 84, + 0xFB8: 84, + 0xFB9: 84, + 0xFBA: 84, + 0xFBB: 84, + 0xFBC: 84, + 0xFC6: 84, + 0x102D: 84, + 0x102E: 84, + 0x102F: 84, + 0x1030: 84, + 0x1032: 84, + 0x1033: 84, + 0x1034: 84, + 0x1035: 84, + 0x1036: 84, + 0x1037: 84, + 0x1039: 84, + 0x103A: 84, + 0x103D: 84, + 0x103E: 84, + 0x1058: 84, + 0x1059: 84, + 0x105E: 84, + 0x105F: 84, + 0x1060: 84, + 0x1071: 84, + 0x1072: 84, + 0x1073: 84, + 0x1074: 84, + 0x1082: 84, + 0x1085: 84, + 0x1086: 84, + 0x108D: 84, + 0x109D: 84, + 0x135D: 84, + 0x135E: 84, + 0x135F: 84, + 0x1712: 84, + 0x1713: 84, + 0x1714: 84, + 0x1732: 84, + 0x1733: 84, + 0x1752: 84, + 0x1753: 84, + 0x1772: 84, + 0x1773: 84, + 0x17B4: 84, + 0x17B5: 84, + 0x17B7: 84, + 0x17B8: 84, + 0x17B9: 84, + 0x17BA: 84, + 0x17BB: 84, + 0x17BC: 84, + 0x17BD: 84, + 0x17C6: 84, + 0x17C9: 84, + 0x17CA: 84, + 0x17CB: 84, + 0x17CC: 84, + 0x17CD: 84, + 0x17CE: 84, + 0x17CF: 84, + 0x17D0: 84, + 0x17D1: 84, + 0x17D2: 84, + 0x17D3: 84, + 0x17DD: 84, + 0x1807: 68, + 0x180A: 67, + 0x180B: 84, + 0x180C: 84, + 0x180D: 84, + 0x180F: 84, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182A: 68, + 0x182B: 68, + 0x182C: 68, + 0x182D: 68, + 0x182E: 68, + 0x182F: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183A: 68, + 0x183B: 68, + 0x183C: 68, + 0x183D: 68, + 0x183E: 68, + 0x183F: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184A: 68, + 0x184B: 68, + 0x184C: 68, + 0x184D: 68, + 0x184E: 68, + 0x184F: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185A: 68, + 0x185B: 68, + 0x185C: 68, + 0x185D: 68, + 0x185E: 68, + 0x185F: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186A: 68, + 0x186B: 68, + 0x186C: 68, + 0x186D: 68, + 0x186E: 68, + 0x186F: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1878: 68, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188A: 68, + 0x188B: 68, + 0x188C: 68, + 0x188D: 68, + 0x188E: 68, + 0x188F: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189A: 68, + 0x189B: 68, + 0x189C: 68, + 0x189D: 68, + 0x189E: 68, + 0x189F: 68, + 0x18A0: 68, + 0x18A1: 68, + 0x18A2: 68, + 0x18A3: 68, + 0x18A4: 68, + 0x18A5: 68, + 0x18A6: 68, + 0x18A7: 68, + 0x18A8: 68, + 0x18A9: 84, + 0x18AA: 68, + 0x1920: 84, + 0x1921: 84, + 0x1922: 84, + 0x1927: 84, + 0x1928: 84, + 0x1932: 84, + 0x1939: 84, + 0x193A: 84, + 0x193B: 84, + 0x1A17: 84, + 0x1A18: 84, + 0x1A1B: 84, + 0x1A56: 84, + 0x1A58: 84, + 0x1A59: 84, + 0x1A5A: 84, + 0x1A5B: 84, + 0x1A5C: 84, + 0x1A5D: 84, + 0x1A5E: 84, + 0x1A60: 84, + 0x1A62: 84, + 0x1A65: 84, + 0x1A66: 84, + 0x1A67: 84, + 0x1A68: 84, + 0x1A69: 84, + 0x1A6A: 84, + 0x1A6B: 84, + 0x1A6C: 84, + 0x1A73: 84, + 0x1A74: 84, + 0x1A75: 84, + 0x1A76: 84, + 0x1A77: 84, + 0x1A78: 84, + 0x1A79: 84, + 0x1A7A: 84, + 0x1A7B: 84, + 0x1A7C: 84, + 0x1A7F: 84, + 0x1AB0: 84, + 0x1AB1: 84, + 0x1AB2: 84, + 0x1AB3: 84, + 0x1AB4: 84, + 0x1AB5: 84, + 0x1AB6: 84, + 0x1AB7: 84, + 0x1AB8: 84, + 0x1AB9: 84, + 0x1ABA: 84, + 0x1ABB: 84, + 0x1ABC: 84, + 0x1ABD: 84, + 0x1ABE: 84, + 0x1ABF: 84, + 0x1AC0: 84, + 0x1AC1: 84, + 0x1AC2: 84, + 0x1AC3: 84, + 0x1AC4: 84, + 0x1AC5: 84, + 0x1AC6: 84, + 0x1AC7: 84, + 0x1AC8: 84, + 0x1AC9: 84, + 0x1ACA: 84, + 0x1ACB: 84, + 0x1ACC: 84, + 0x1ACD: 84, + 0x1ACE: 84, + 0x1B00: 84, + 0x1B01: 84, + 0x1B02: 84, + 0x1B03: 84, + 0x1B34: 84, + 0x1B36: 84, + 0x1B37: 84, + 0x1B38: 84, + 0x1B39: 84, + 0x1B3A: 84, + 0x1B3C: 84, + 0x1B42: 84, + 0x1B6B: 84, + 0x1B6C: 84, + 0x1B6D: 84, + 0x1B6E: 84, + 0x1B6F: 84, + 0x1B70: 84, + 0x1B71: 84, + 0x1B72: 84, + 0x1B73: 84, + 0x1B80: 84, + 0x1B81: 84, + 0x1BA2: 84, + 0x1BA3: 84, + 0x1BA4: 84, + 0x1BA5: 84, + 0x1BA8: 84, + 0x1BA9: 84, + 0x1BAB: 84, + 0x1BAC: 84, + 0x1BAD: 84, + 0x1BE6: 84, + 0x1BE8: 84, + 0x1BE9: 84, + 0x1BED: 84, + 0x1BEF: 84, + 0x1BF0: 84, + 0x1BF1: 84, + 0x1C2C: 84, + 0x1C2D: 84, + 0x1C2E: 84, + 0x1C2F: 84, + 0x1C30: 84, + 0x1C31: 84, + 0x1C32: 84, + 0x1C33: 84, + 0x1C36: 84, + 0x1C37: 84, + 0x1CD0: 84, + 0x1CD1: 84, + 0x1CD2: 84, + 0x1CD4: 84, + 0x1CD5: 84, + 0x1CD6: 84, + 0x1CD7: 84, + 0x1CD8: 84, + 0x1CD9: 84, + 0x1CDA: 84, + 0x1CDB: 84, + 0x1CDC: 84, + 0x1CDD: 84, + 0x1CDE: 84, + 0x1CDF: 84, + 0x1CE0: 84, + 0x1CE2: 84, + 0x1CE3: 84, + 0x1CE4: 84, + 0x1CE5: 84, + 0x1CE6: 84, + 0x1CE7: 84, + 0x1CE8: 84, + 0x1CED: 84, + 0x1CF4: 84, + 0x1CF8: 84, + 0x1CF9: 84, + 0x1DC0: 84, + 0x1DC1: 84, + 0x1DC2: 84, + 0x1DC3: 84, + 0x1DC4: 84, + 0x1DC5: 84, + 0x1DC6: 84, + 0x1DC7: 84, + 0x1DC8: 84, + 0x1DC9: 84, + 0x1DCA: 84, + 0x1DCB: 84, + 0x1DCC: 84, + 0x1DCD: 84, + 0x1DCE: 84, + 0x1DCF: 84, + 0x1DD0: 84, + 0x1DD1: 84, + 0x1DD2: 84, + 0x1DD3: 84, + 0x1DD4: 84, + 0x1DD5: 84, + 0x1DD6: 84, + 0x1DD7: 84, + 0x1DD8: 84, + 0x1DD9: 84, + 0x1DDA: 84, + 0x1DDB: 84, + 0x1DDC: 84, + 0x1DDD: 84, + 0x1DDE: 84, + 0x1DDF: 84, + 0x1DE0: 84, + 0x1DE1: 84, + 0x1DE2: 84, + 0x1DE3: 84, + 0x1DE4: 84, + 0x1DE5: 84, + 0x1DE6: 84, + 0x1DE7: 84, + 0x1DE8: 84, + 0x1DE9: 84, + 0x1DEA: 84, + 0x1DEB: 84, + 0x1DEC: 84, + 0x1DED: 84, + 0x1DEE: 84, + 0x1DEF: 84, + 0x1DF0: 84, + 0x1DF1: 84, + 0x1DF2: 84, + 0x1DF3: 84, + 0x1DF4: 84, + 0x1DF5: 84, + 0x1DF6: 84, + 0x1DF7: 84, + 0x1DF8: 84, + 0x1DF9: 84, + 0x1DFA: 84, + 0x1DFB: 84, + 0x1DFC: 84, + 0x1DFD: 84, + 0x1DFE: 84, + 0x1DFF: 84, + 0x200B: 84, + 0x200D: 67, + 0x200E: 84, + 0x200F: 84, + 0x202A: 84, + 0x202B: 84, + 0x202C: 84, + 0x202D: 84, + 0x202E: 84, + 0x2060: 84, + 0x2061: 84, + 0x2062: 84, + 0x2063: 84, + 0x2064: 84, + 0x206A: 84, + 0x206B: 84, + 0x206C: 84, + 0x206D: 84, + 0x206E: 84, + 0x206F: 84, + 0x20D0: 84, + 0x20D1: 84, + 0x20D2: 84, + 0x20D3: 84, + 0x20D4: 84, + 0x20D5: 84, + 0x20D6: 84, + 0x20D7: 84, + 0x20D8: 84, + 0x20D9: 84, + 0x20DA: 84, + 0x20DB: 84, + 0x20DC: 84, + 0x20DD: 84, + 0x20DE: 84, + 0x20DF: 84, + 0x20E0: 84, + 0x20E1: 84, + 0x20E2: 84, + 0x20E3: 84, + 0x20E4: 84, + 0x20E5: 84, + 0x20E6: 84, + 0x20E7: 84, + 0x20E8: 84, + 0x20E9: 84, + 0x20EA: 84, + 0x20EB: 84, + 0x20EC: 84, + 0x20ED: 84, + 0x20EE: 84, + 0x20EF: 84, + 0x20F0: 84, + 0x2CEF: 84, + 0x2CF0: 84, + 0x2CF1: 84, + 0x2D7F: 84, + 0x2DE0: 84, + 0x2DE1: 84, + 0x2DE2: 84, + 0x2DE3: 84, + 0x2DE4: 84, + 0x2DE5: 84, + 0x2DE6: 84, + 0x2DE7: 84, + 0x2DE8: 84, + 0x2DE9: 84, + 0x2DEA: 84, + 0x2DEB: 84, + 0x2DEC: 84, + 0x2DED: 84, + 0x2DEE: 84, + 0x2DEF: 84, + 0x2DF0: 84, + 0x2DF1: 84, + 0x2DF2: 84, + 0x2DF3: 84, + 0x2DF4: 84, + 0x2DF5: 84, + 0x2DF6: 84, + 0x2DF7: 84, + 0x2DF8: 84, + 0x2DF9: 84, + 0x2DFA: 84, + 0x2DFB: 84, + 0x2DFC: 84, + 0x2DFD: 84, + 0x2DFE: 84, + 0x2DFF: 84, + 0x302A: 84, + 0x302B: 84, + 0x302C: 84, + 0x302D: 84, + 0x3099: 84, + 0x309A: 84, + 0xA66F: 84, + 0xA670: 84, + 0xA671: 84, + 0xA672: 84, + 0xA674: 84, + 0xA675: 84, + 0xA676: 84, + 0xA677: 84, + 0xA678: 84, + 0xA679: 84, + 0xA67A: 84, + 0xA67B: 84, + 0xA67C: 84, + 0xA67D: 84, + 0xA69E: 84, + 0xA69F: 84, + 0xA6F0: 84, + 0xA6F1: 84, + 0xA802: 84, + 0xA806: 84, + 0xA80B: 84, + 0xA825: 84, + 0xA826: 84, + 0xA82C: 84, + 0xA840: 68, + 0xA841: 68, + 0xA842: 68, + 0xA843: 68, + 0xA844: 68, + 0xA845: 68, + 0xA846: 68, + 0xA847: 68, + 0xA848: 68, + 0xA849: 68, + 0xA84A: 68, + 0xA84B: 68, + 0xA84C: 68, + 0xA84D: 68, + 0xA84E: 68, + 0xA84F: 68, + 0xA850: 68, + 0xA851: 68, + 0xA852: 68, + 0xA853: 68, + 0xA854: 68, + 0xA855: 68, + 0xA856: 68, + 0xA857: 68, + 0xA858: 68, + 0xA859: 68, + 0xA85A: 68, + 0xA85B: 68, + 0xA85C: 68, + 0xA85D: 68, + 0xA85E: 68, + 0xA85F: 68, + 0xA860: 68, + 0xA861: 68, + 0xA862: 68, + 0xA863: 68, + 0xA864: 68, + 0xA865: 68, + 0xA866: 68, + 0xA867: 68, + 0xA868: 68, + 0xA869: 68, + 0xA86A: 68, + 0xA86B: 68, + 0xA86C: 68, + 0xA86D: 68, + 0xA86E: 68, + 0xA86F: 68, + 0xA870: 68, + 0xA871: 68, + 0xA872: 76, + 0xA8C4: 84, + 0xA8C5: 84, + 0xA8E0: 84, + 0xA8E1: 84, + 0xA8E2: 84, + 0xA8E3: 84, + 0xA8E4: 84, + 0xA8E5: 84, + 0xA8E6: 84, + 0xA8E7: 84, + 0xA8E8: 84, + 0xA8E9: 84, + 0xA8EA: 84, + 0xA8EB: 84, + 0xA8EC: 84, + 0xA8ED: 84, + 0xA8EE: 84, + 0xA8EF: 84, + 0xA8F0: 84, + 0xA8F1: 84, + 0xA8FF: 84, + 0xA926: 84, + 0xA927: 84, + 0xA928: 84, + 0xA929: 84, + 0xA92A: 84, + 0xA92B: 84, + 0xA92C: 84, + 0xA92D: 84, + 0xA947: 84, + 0xA948: 84, + 0xA949: 84, + 0xA94A: 84, + 0xA94B: 84, + 0xA94C: 84, + 0xA94D: 84, + 0xA94E: 84, + 0xA94F: 84, + 0xA950: 84, + 0xA951: 84, + 0xA980: 84, + 0xA981: 84, + 0xA982: 84, + 0xA9B3: 84, + 0xA9B6: 84, + 0xA9B7: 84, + 0xA9B8: 84, + 0xA9B9: 84, + 0xA9BC: 84, + 0xA9BD: 84, + 0xA9E5: 84, + 0xAA29: 84, + 0xAA2A: 84, + 0xAA2B: 84, + 0xAA2C: 84, + 0xAA2D: 84, + 0xAA2E: 84, + 0xAA31: 84, + 0xAA32: 84, + 0xAA35: 84, + 0xAA36: 84, + 0xAA43: 84, + 0xAA4C: 84, + 0xAA7C: 84, + 0xAAB0: 84, + 0xAAB2: 84, + 0xAAB3: 84, + 0xAAB4: 84, + 0xAAB7: 84, + 0xAAB8: 84, + 0xAABE: 84, + 0xAABF: 84, + 0xAAC1: 84, + 0xAAEC: 84, + 0xAAED: 84, + 0xAAF6: 84, + 0xABE5: 84, + 0xABE8: 84, + 0xABED: 84, + 0xFB1E: 84, + 0xFE00: 84, + 0xFE01: 84, + 0xFE02: 84, + 0xFE03: 84, + 0xFE04: 84, + 0xFE05: 84, + 0xFE06: 84, + 0xFE07: 84, + 0xFE08: 84, + 0xFE09: 84, + 0xFE0A: 84, + 0xFE0B: 84, + 0xFE0C: 84, + 0xFE0D: 84, + 0xFE0E: 84, + 0xFE0F: 84, + 0xFE20: 84, + 0xFE21: 84, + 0xFE22: 84, + 0xFE23: 84, + 0xFE24: 84, + 0xFE25: 84, + 0xFE26: 84, + 0xFE27: 84, + 0xFE28: 84, + 0xFE29: 84, + 0xFE2A: 84, + 0xFE2B: 84, + 0xFE2C: 84, + 0xFE2D: 84, + 0xFE2E: 84, + 0xFE2F: 84, + 0xFEFF: 84, + 0xFFF9: 84, + 0xFFFA: 84, + 0xFFFB: 84, + 0x101FD: 84, + 0x102E0: 84, + 0x10376: 84, + 0x10377: 84, + 0x10378: 84, + 0x10379: 84, + 0x1037A: 84, + 0x10A01: 84, + 0x10A02: 84, + 0x10A03: 84, + 0x10A05: 84, + 0x10A06: 84, + 0x10A0C: 84, + 0x10A0D: 84, + 0x10A0E: 84, + 0x10A0F: 84, + 0x10A38: 84, + 0x10A39: 84, + 0x10A3A: 84, + 0x10A3F: 84, + 0x10AC0: 68, + 0x10AC1: 68, + 0x10AC2: 68, + 0x10AC3: 68, + 0x10AC4: 68, + 0x10AC5: 82, + 0x10AC7: 82, + 0x10AC9: 82, + 0x10ACA: 82, + 0x10ACD: 76, + 0x10ACE: 82, + 0x10ACF: 82, + 0x10AD0: 82, + 0x10AD1: 82, + 0x10AD2: 82, + 0x10AD3: 68, + 0x10AD4: 68, + 0x10AD5: 68, + 0x10AD6: 68, + 0x10AD7: 76, + 0x10AD8: 68, + 0x10AD9: 68, + 0x10ADA: 68, + 0x10ADB: 68, + 0x10ADC: 68, + 0x10ADD: 82, + 0x10ADE: 68, + 0x10ADF: 68, + 0x10AE0: 68, + 0x10AE1: 82, + 0x10AE4: 82, + 0x10AE5: 84, + 0x10AE6: 84, + 0x10AEB: 68, + 0x10AEC: 68, + 0x10AED: 68, + 0x10AEE: 68, + 0x10AEF: 82, + 0x10B80: 68, + 0x10B81: 82, + 0x10B82: 68, + 0x10B83: 82, + 0x10B84: 82, + 0x10B85: 82, + 0x10B86: 68, + 0x10B87: 68, + 0x10B88: 68, + 0x10B89: 82, + 0x10B8A: 68, + 0x10B8B: 68, + 0x10B8C: 82, + 0x10B8D: 68, + 0x10B8E: 82, + 0x10B8F: 82, + 0x10B90: 68, + 0x10B91: 82, + 0x10BA9: 82, + 0x10BAA: 82, + 0x10BAB: 82, + 0x10BAC: 82, + 0x10BAD: 68, + 0x10BAE: 68, + 0x10D00: 76, + 0x10D01: 68, + 0x10D02: 68, + 0x10D03: 68, + 0x10D04: 68, + 0x10D05: 68, + 0x10D06: 68, + 0x10D07: 68, + 0x10D08: 68, + 0x10D09: 68, + 0x10D0A: 68, + 0x10D0B: 68, + 0x10D0C: 68, + 0x10D0D: 68, + 0x10D0E: 68, + 0x10D0F: 68, + 0x10D10: 68, + 0x10D11: 68, + 0x10D12: 68, + 0x10D13: 68, + 0x10D14: 68, + 0x10D15: 68, + 0x10D16: 68, + 0x10D17: 68, + 0x10D18: 68, + 0x10D19: 68, + 0x10D1A: 68, + 0x10D1B: 68, + 0x10D1C: 68, + 0x10D1D: 68, + 0x10D1E: 68, + 0x10D1F: 68, + 0x10D20: 68, + 0x10D21: 68, + 0x10D22: 82, + 0x10D23: 68, + 0x10D24: 84, + 0x10D25: 84, + 0x10D26: 84, + 0x10D27: 84, + 0x10EAB: 84, + 0x10EAC: 84, + 0x10EFD: 84, + 0x10EFE: 84, + 0x10EFF: 84, + 0x10F30: 68, + 0x10F31: 68, + 0x10F32: 68, + 0x10F33: 82, + 0x10F34: 68, + 0x10F35: 68, + 0x10F36: 68, + 0x10F37: 68, + 0x10F38: 68, + 0x10F39: 68, + 0x10F3A: 68, + 0x10F3B: 68, + 0x10F3C: 68, + 0x10F3D: 68, + 0x10F3E: 68, + 0x10F3F: 68, + 0x10F40: 68, + 0x10F41: 68, + 0x10F42: 68, + 0x10F43: 68, + 0x10F44: 68, + 0x10F46: 84, + 0x10F47: 84, + 0x10F48: 84, + 0x10F49: 84, + 0x10F4A: 84, + 0x10F4B: 84, + 0x10F4C: 84, + 0x10F4D: 84, + 0x10F4E: 84, + 0x10F4F: 84, + 0x10F50: 84, + 0x10F51: 68, + 0x10F52: 68, + 0x10F53: 68, + 0x10F54: 82, + 0x10F70: 68, + 0x10F71: 68, + 0x10F72: 68, + 0x10F73: 68, + 0x10F74: 82, + 0x10F75: 82, + 0x10F76: 68, + 0x10F77: 68, + 0x10F78: 68, + 0x10F79: 68, + 0x10F7A: 68, + 0x10F7B: 68, + 0x10F7C: 68, + 0x10F7D: 68, + 0x10F7E: 68, + 0x10F7F: 68, + 0x10F80: 68, + 0x10F81: 68, + 0x10F82: 84, + 0x10F83: 84, + 0x10F84: 84, + 0x10F85: 84, + 0x10FB0: 68, + 0x10FB2: 68, + 0x10FB3: 68, + 0x10FB4: 82, + 0x10FB5: 82, + 0x10FB6: 82, + 0x10FB8: 68, + 0x10FB9: 82, + 0x10FBA: 82, + 0x10FBB: 68, + 0x10FBC: 68, + 0x10FBD: 82, + 0x10FBE: 68, + 0x10FBF: 68, + 0x10FC1: 68, + 0x10FC2: 82, + 0x10FC3: 82, + 0x10FC4: 68, + 0x10FC9: 82, + 0x10FCA: 68, + 0x10FCB: 76, + 0x11001: 84, + 0x11038: 84, + 0x11039: 84, + 0x1103A: 84, + 0x1103B: 84, + 0x1103C: 84, + 0x1103D: 84, + 0x1103E: 84, + 0x1103F: 84, + 0x11040: 84, + 0x11041: 84, + 0x11042: 84, + 0x11043: 84, + 0x11044: 84, + 0x11045: 84, + 0x11046: 84, + 0x11070: 84, + 0x11073: 84, + 0x11074: 84, + 0x1107F: 84, + 0x11080: 84, + 0x11081: 84, + 0x110B3: 84, + 0x110B4: 84, + 0x110B5: 84, + 0x110B6: 84, + 0x110B9: 84, + 0x110BA: 84, + 0x110C2: 84, + 0x11100: 84, + 0x11101: 84, + 0x11102: 84, + 0x11127: 84, + 0x11128: 84, + 0x11129: 84, + 0x1112A: 84, + 0x1112B: 84, + 0x1112D: 84, + 0x1112E: 84, + 0x1112F: 84, + 0x11130: 84, + 0x11131: 84, + 0x11132: 84, + 0x11133: 84, + 0x11134: 84, + 0x11173: 84, + 0x11180: 84, + 0x11181: 84, + 0x111B6: 84, + 0x111B7: 84, + 0x111B8: 84, + 0x111B9: 84, + 0x111BA: 84, + 0x111BB: 84, + 0x111BC: 84, + 0x111BD: 84, + 0x111BE: 84, + 0x111C9: 84, + 0x111CA: 84, + 0x111CB: 84, + 0x111CC: 84, + 0x111CF: 84, + 0x1122F: 84, + 0x11230: 84, + 0x11231: 84, + 0x11234: 84, + 0x11236: 84, + 0x11237: 84, + 0x1123E: 84, + 0x11241: 84, + 0x112DF: 84, + 0x112E3: 84, + 0x112E4: 84, + 0x112E5: 84, + 0x112E6: 84, + 0x112E7: 84, + 0x112E8: 84, + 0x112E9: 84, + 0x112EA: 84, + 0x11300: 84, + 0x11301: 84, + 0x1133B: 84, + 0x1133C: 84, + 0x11340: 84, + 0x11366: 84, + 0x11367: 84, + 0x11368: 84, + 0x11369: 84, + 0x1136A: 84, + 0x1136B: 84, + 0x1136C: 84, + 0x11370: 84, + 0x11371: 84, + 0x11372: 84, + 0x11373: 84, + 0x11374: 84, + 0x11438: 84, + 0x11439: 84, + 0x1143A: 84, + 0x1143B: 84, + 0x1143C: 84, + 0x1143D: 84, + 0x1143E: 84, + 0x1143F: 84, + 0x11442: 84, + 0x11443: 84, + 0x11444: 84, + 0x11446: 84, + 0x1145E: 84, + 0x114B3: 84, + 0x114B4: 84, + 0x114B5: 84, + 0x114B6: 84, + 0x114B7: 84, + 0x114B8: 84, + 0x114BA: 84, + 0x114BF: 84, + 0x114C0: 84, + 0x114C2: 84, + 0x114C3: 84, + 0x115B2: 84, + 0x115B3: 84, + 0x115B4: 84, + 0x115B5: 84, + 0x115BC: 84, + 0x115BD: 84, + 0x115BF: 84, + 0x115C0: 84, + 0x115DC: 84, + 0x115DD: 84, + 0x11633: 84, + 0x11634: 84, + 0x11635: 84, + 0x11636: 84, + 0x11637: 84, + 0x11638: 84, + 0x11639: 84, + 0x1163A: 84, + 0x1163D: 84, + 0x1163F: 84, + 0x11640: 84, + 0x116AB: 84, + 0x116AD: 84, + 0x116B0: 84, + 0x116B1: 84, + 0x116B2: 84, + 0x116B3: 84, + 0x116B4: 84, + 0x116B5: 84, + 0x116B7: 84, + 0x1171D: 84, + 0x1171E: 84, + 0x1171F: 84, + 0x11722: 84, + 0x11723: 84, + 0x11724: 84, + 0x11725: 84, + 0x11727: 84, + 0x11728: 84, + 0x11729: 84, + 0x1172A: 84, + 0x1172B: 84, + 0x1182F: 84, + 0x11830: 84, + 0x11831: 84, + 0x11832: 84, + 0x11833: 84, + 0x11834: 84, + 0x11835: 84, + 0x11836: 84, + 0x11837: 84, + 0x11839: 84, + 0x1183A: 84, + 0x1193B: 84, + 0x1193C: 84, + 0x1193E: 84, + 0x11943: 84, + 0x119D4: 84, + 0x119D5: 84, + 0x119D6: 84, + 0x119D7: 84, + 0x119DA: 84, + 0x119DB: 84, + 0x119E0: 84, + 0x11A01: 84, + 0x11A02: 84, + 0x11A03: 84, + 0x11A04: 84, + 0x11A05: 84, + 0x11A06: 84, + 0x11A07: 84, + 0x11A08: 84, + 0x11A09: 84, + 0x11A0A: 84, + 0x11A33: 84, + 0x11A34: 84, + 0x11A35: 84, + 0x11A36: 84, + 0x11A37: 84, + 0x11A38: 84, + 0x11A3B: 84, + 0x11A3C: 84, + 0x11A3D: 84, + 0x11A3E: 84, + 0x11A47: 84, + 0x11A51: 84, + 0x11A52: 84, + 0x11A53: 84, + 0x11A54: 84, + 0x11A55: 84, + 0x11A56: 84, + 0x11A59: 84, + 0x11A5A: 84, + 0x11A5B: 84, + 0x11A8A: 84, + 0x11A8B: 84, + 0x11A8C: 84, + 0x11A8D: 84, + 0x11A8E: 84, + 0x11A8F: 84, + 0x11A90: 84, + 0x11A91: 84, + 0x11A92: 84, + 0x11A93: 84, + 0x11A94: 84, + 0x11A95: 84, + 0x11A96: 84, + 0x11A98: 84, + 0x11A99: 84, + 0x11C30: 84, + 0x11C31: 84, + 0x11C32: 84, + 0x11C33: 84, + 0x11C34: 84, + 0x11C35: 84, + 0x11C36: 84, + 0x11C38: 84, + 0x11C39: 84, + 0x11C3A: 84, + 0x11C3B: 84, + 0x11C3C: 84, + 0x11C3D: 84, + 0x11C3F: 84, + 0x11C92: 84, + 0x11C93: 84, + 0x11C94: 84, + 0x11C95: 84, + 0x11C96: 84, + 0x11C97: 84, + 0x11C98: 84, + 0x11C99: 84, + 0x11C9A: 84, + 0x11C9B: 84, + 0x11C9C: 84, + 0x11C9D: 84, + 0x11C9E: 84, + 0x11C9F: 84, + 0x11CA0: 84, + 0x11CA1: 84, + 0x11CA2: 84, + 0x11CA3: 84, + 0x11CA4: 84, + 0x11CA5: 84, + 0x11CA6: 84, + 0x11CA7: 84, + 0x11CAA: 84, + 0x11CAB: 84, + 0x11CAC: 84, + 0x11CAD: 84, + 0x11CAE: 84, + 0x11CAF: 84, + 0x11CB0: 84, + 0x11CB2: 84, + 0x11CB3: 84, + 0x11CB5: 84, + 0x11CB6: 84, + 0x11D31: 84, + 0x11D32: 84, + 0x11D33: 84, + 0x11D34: 84, + 0x11D35: 84, + 0x11D36: 84, + 0x11D3A: 84, + 0x11D3C: 84, + 0x11D3D: 84, + 0x11D3F: 84, + 0x11D40: 84, + 0x11D41: 84, + 0x11D42: 84, + 0x11D43: 84, + 0x11D44: 84, + 0x11D45: 84, + 0x11D47: 84, + 0x11D90: 84, + 0x11D91: 84, + 0x11D95: 84, + 0x11D97: 84, + 0x11EF3: 84, + 0x11EF4: 84, + 0x11F00: 84, + 0x11F01: 84, + 0x11F36: 84, + 0x11F37: 84, + 0x11F38: 84, + 0x11F39: 84, + 0x11F3A: 84, + 0x11F40: 84, + 0x11F42: 84, + 0x13430: 84, + 0x13431: 84, + 0x13432: 84, + 0x13433: 84, + 0x13434: 84, + 0x13435: 84, + 0x13436: 84, + 0x13437: 84, + 0x13438: 84, + 0x13439: 84, + 0x1343A: 84, + 0x1343B: 84, + 0x1343C: 84, + 0x1343D: 84, + 0x1343E: 84, + 0x1343F: 84, + 0x13440: 84, + 0x13447: 84, + 0x13448: 84, + 0x13449: 84, + 0x1344A: 84, + 0x1344B: 84, + 0x1344C: 84, + 0x1344D: 84, + 0x1344E: 84, + 0x1344F: 84, + 0x13450: 84, + 0x13451: 84, + 0x13452: 84, + 0x13453: 84, + 0x13454: 84, + 0x13455: 84, + 0x16AF0: 84, + 0x16AF1: 84, + 0x16AF2: 84, + 0x16AF3: 84, + 0x16AF4: 84, + 0x16B30: 84, + 0x16B31: 84, + 0x16B32: 84, + 0x16B33: 84, + 0x16B34: 84, + 0x16B35: 84, + 0x16B36: 84, + 0x16F4F: 84, + 0x16F8F: 84, + 0x16F90: 84, + 0x16F91: 84, + 0x16F92: 84, + 0x16FE4: 84, + 0x1BC9D: 84, + 0x1BC9E: 84, + 0x1BCA0: 84, + 0x1BCA1: 84, + 0x1BCA2: 84, + 0x1BCA3: 84, + 0x1CF00: 84, + 0x1CF01: 84, + 0x1CF02: 84, + 0x1CF03: 84, + 0x1CF04: 84, + 0x1CF05: 84, + 0x1CF06: 84, + 0x1CF07: 84, + 0x1CF08: 84, + 0x1CF09: 84, + 0x1CF0A: 84, + 0x1CF0B: 84, + 0x1CF0C: 84, + 0x1CF0D: 84, + 0x1CF0E: 84, + 0x1CF0F: 84, + 0x1CF10: 84, + 0x1CF11: 84, + 0x1CF12: 84, + 0x1CF13: 84, + 0x1CF14: 84, + 0x1CF15: 84, + 0x1CF16: 84, + 0x1CF17: 84, + 0x1CF18: 84, + 0x1CF19: 84, + 0x1CF1A: 84, + 0x1CF1B: 84, + 0x1CF1C: 84, + 0x1CF1D: 84, + 0x1CF1E: 84, + 0x1CF1F: 84, + 0x1CF20: 84, + 0x1CF21: 84, + 0x1CF22: 84, + 0x1CF23: 84, + 0x1CF24: 84, + 0x1CF25: 84, + 0x1CF26: 84, + 0x1CF27: 84, + 0x1CF28: 84, + 0x1CF29: 84, + 0x1CF2A: 84, + 0x1CF2B: 84, + 0x1CF2C: 84, + 0x1CF2D: 84, + 0x1CF30: 84, + 0x1CF31: 84, + 0x1CF32: 84, + 0x1CF33: 84, + 0x1CF34: 84, + 0x1CF35: 84, + 0x1CF36: 84, + 0x1CF37: 84, + 0x1CF38: 84, + 0x1CF39: 84, + 0x1CF3A: 84, + 0x1CF3B: 84, + 0x1CF3C: 84, + 0x1CF3D: 84, + 0x1CF3E: 84, + 0x1CF3F: 84, + 0x1CF40: 84, + 0x1CF41: 84, + 0x1CF42: 84, + 0x1CF43: 84, + 0x1CF44: 84, + 0x1CF45: 84, + 0x1CF46: 84, + 0x1D167: 84, + 0x1D168: 84, + 0x1D169: 84, + 0x1D173: 84, + 0x1D174: 84, + 0x1D175: 84, + 0x1D176: 84, + 0x1D177: 84, + 0x1D178: 84, + 0x1D179: 84, + 0x1D17A: 84, + 0x1D17B: 84, + 0x1D17C: 84, + 0x1D17D: 84, + 0x1D17E: 84, + 0x1D17F: 84, + 0x1D180: 84, + 0x1D181: 84, + 0x1D182: 84, + 0x1D185: 84, + 0x1D186: 84, + 0x1D187: 84, + 0x1D188: 84, + 0x1D189: 84, + 0x1D18A: 84, + 0x1D18B: 84, + 0x1D1AA: 84, + 0x1D1AB: 84, + 0x1D1AC: 84, + 0x1D1AD: 84, + 0x1D242: 84, + 0x1D243: 84, + 0x1D244: 84, + 0x1DA00: 84, + 0x1DA01: 84, + 0x1DA02: 84, + 0x1DA03: 84, + 0x1DA04: 84, + 0x1DA05: 84, + 0x1DA06: 84, + 0x1DA07: 84, + 0x1DA08: 84, + 0x1DA09: 84, + 0x1DA0A: 84, + 0x1DA0B: 84, + 0x1DA0C: 84, + 0x1DA0D: 84, + 0x1DA0E: 84, + 0x1DA0F: 84, + 0x1DA10: 84, + 0x1DA11: 84, + 0x1DA12: 84, + 0x1DA13: 84, + 0x1DA14: 84, + 0x1DA15: 84, + 0x1DA16: 84, + 0x1DA17: 84, + 0x1DA18: 84, + 0x1DA19: 84, + 0x1DA1A: 84, + 0x1DA1B: 84, + 0x1DA1C: 84, + 0x1DA1D: 84, + 0x1DA1E: 84, + 0x1DA1F: 84, + 0x1DA20: 84, + 0x1DA21: 84, + 0x1DA22: 84, + 0x1DA23: 84, + 0x1DA24: 84, + 0x1DA25: 84, + 0x1DA26: 84, + 0x1DA27: 84, + 0x1DA28: 84, + 0x1DA29: 84, + 0x1DA2A: 84, + 0x1DA2B: 84, + 0x1DA2C: 84, + 0x1DA2D: 84, + 0x1DA2E: 84, + 0x1DA2F: 84, + 0x1DA30: 84, + 0x1DA31: 84, + 0x1DA32: 84, + 0x1DA33: 84, + 0x1DA34: 84, + 0x1DA35: 84, + 0x1DA36: 84, + 0x1DA3B: 84, + 0x1DA3C: 84, + 0x1DA3D: 84, + 0x1DA3E: 84, + 0x1DA3F: 84, + 0x1DA40: 84, + 0x1DA41: 84, + 0x1DA42: 84, + 0x1DA43: 84, + 0x1DA44: 84, + 0x1DA45: 84, + 0x1DA46: 84, + 0x1DA47: 84, + 0x1DA48: 84, + 0x1DA49: 84, + 0x1DA4A: 84, + 0x1DA4B: 84, + 0x1DA4C: 84, + 0x1DA4D: 84, + 0x1DA4E: 84, + 0x1DA4F: 84, + 0x1DA50: 84, + 0x1DA51: 84, + 0x1DA52: 84, + 0x1DA53: 84, + 0x1DA54: 84, + 0x1DA55: 84, + 0x1DA56: 84, + 0x1DA57: 84, + 0x1DA58: 84, + 0x1DA59: 84, + 0x1DA5A: 84, + 0x1DA5B: 84, + 0x1DA5C: 84, + 0x1DA5D: 84, + 0x1DA5E: 84, + 0x1DA5F: 84, + 0x1DA60: 84, + 0x1DA61: 84, + 0x1DA62: 84, + 0x1DA63: 84, + 0x1DA64: 84, + 0x1DA65: 84, + 0x1DA66: 84, + 0x1DA67: 84, + 0x1DA68: 84, + 0x1DA69: 84, + 0x1DA6A: 84, + 0x1DA6B: 84, + 0x1DA6C: 84, + 0x1DA75: 84, + 0x1DA84: 84, + 0x1DA9B: 84, + 0x1DA9C: 84, + 0x1DA9D: 84, + 0x1DA9E: 84, + 0x1DA9F: 84, + 0x1DAA1: 84, + 0x1DAA2: 84, + 0x1DAA3: 84, + 0x1DAA4: 84, + 0x1DAA5: 84, + 0x1DAA6: 84, + 0x1DAA7: 84, + 0x1DAA8: 84, + 0x1DAA9: 84, + 0x1DAAA: 84, + 0x1DAAB: 84, + 0x1DAAC: 84, + 0x1DAAD: 84, + 0x1DAAE: 84, + 0x1DAAF: 84, + 0x1E000: 84, + 0x1E001: 84, + 0x1E002: 84, + 0x1E003: 84, + 0x1E004: 84, + 0x1E005: 84, + 0x1E006: 84, + 0x1E008: 84, + 0x1E009: 84, + 0x1E00A: 84, + 0x1E00B: 84, + 0x1E00C: 84, + 0x1E00D: 84, + 0x1E00E: 84, + 0x1E00F: 84, + 0x1E010: 84, + 0x1E011: 84, + 0x1E012: 84, + 0x1E013: 84, + 0x1E014: 84, + 0x1E015: 84, + 0x1E016: 84, + 0x1E017: 84, + 0x1E018: 84, + 0x1E01B: 84, + 0x1E01C: 84, + 0x1E01D: 84, + 0x1E01E: 84, + 0x1E01F: 84, + 0x1E020: 84, + 0x1E021: 84, + 0x1E023: 84, + 0x1E024: 84, + 0x1E026: 84, + 0x1E027: 84, + 0x1E028: 84, + 0x1E029: 84, + 0x1E02A: 84, + 0x1E08F: 84, + 0x1E130: 84, + 0x1E131: 84, + 0x1E132: 84, + 0x1E133: 84, + 0x1E134: 84, + 0x1E135: 84, + 0x1E136: 84, + 0x1E2AE: 84, + 0x1E2EC: 84, + 0x1E2ED: 84, + 0x1E2EE: 84, + 0x1E2EF: 84, + 0x1E4EC: 84, + 0x1E4ED: 84, + 0x1E4EE: 84, + 0x1E4EF: 84, + 0x1E8D0: 84, + 0x1E8D1: 84, + 0x1E8D2: 84, + 0x1E8D3: 84, + 0x1E8D4: 84, + 0x1E8D5: 84, + 0x1E8D6: 84, + 0x1E900: 68, + 0x1E901: 68, + 0x1E902: 68, + 0x1E903: 68, + 0x1E904: 68, + 0x1E905: 68, + 0x1E906: 68, + 0x1E907: 68, + 0x1E908: 68, + 0x1E909: 68, + 0x1E90A: 68, + 0x1E90B: 68, + 0x1E90C: 68, + 0x1E90D: 68, + 0x1E90E: 68, + 0x1E90F: 68, + 0x1E910: 68, + 0x1E911: 68, + 0x1E912: 68, + 0x1E913: 68, + 0x1E914: 68, + 0x1E915: 68, + 0x1E916: 68, + 0x1E917: 68, + 0x1E918: 68, + 0x1E919: 68, + 0x1E91A: 68, + 0x1E91B: 68, + 0x1E91C: 68, + 0x1E91D: 68, + 0x1E91E: 68, + 0x1E91F: 68, + 0x1E920: 68, + 0x1E921: 68, + 0x1E922: 68, + 0x1E923: 68, + 0x1E924: 68, + 0x1E925: 68, + 0x1E926: 68, + 0x1E927: 68, + 0x1E928: 68, + 0x1E929: 68, + 0x1E92A: 68, + 0x1E92B: 68, + 0x1E92C: 68, + 0x1E92D: 68, + 0x1E92E: 68, + 0x1E92F: 68, + 0x1E930: 68, + 0x1E931: 68, + 0x1E932: 68, + 0x1E933: 68, + 0x1E934: 68, + 0x1E935: 68, + 0x1E936: 68, + 0x1E937: 68, + 0x1E938: 68, + 0x1E939: 68, + 0x1E93A: 68, + 0x1E93B: 68, + 0x1E93C: 68, + 0x1E93D: 68, + 0x1E93E: 68, + 0x1E93F: 68, + 0x1E940: 68, + 0x1E941: 68, + 0x1E942: 68, + 0x1E943: 68, + 0x1E944: 84, + 0x1E945: 84, + 0x1E946: 84, + 0x1E947: 84, + 0x1E948: 84, + 0x1E949: 84, + 0x1E94A: 84, + 0x1E94B: 84, + 0xE0001: 84, + 0xE0020: 84, + 0xE0021: 84, + 0xE0022: 84, + 0xE0023: 84, + 0xE0024: 84, + 0xE0025: 84, + 0xE0026: 84, + 0xE0027: 84, + 0xE0028: 84, + 0xE0029: 84, + 0xE002A: 84, + 0xE002B: 84, + 0xE002C: 84, + 0xE002D: 84, + 0xE002E: 84, + 0xE002F: 84, + 0xE0030: 84, + 0xE0031: 84, + 0xE0032: 84, + 0xE0033: 84, + 0xE0034: 84, + 0xE0035: 84, + 0xE0036: 84, + 0xE0037: 84, + 0xE0038: 84, + 0xE0039: 84, + 0xE003A: 84, + 0xE003B: 84, + 0xE003C: 84, + 0xE003D: 84, + 0xE003E: 84, + 0xE003F: 84, + 0xE0040: 84, + 0xE0041: 84, + 0xE0042: 84, + 0xE0043: 84, + 0xE0044: 84, + 0xE0045: 84, + 0xE0046: 84, + 0xE0047: 84, + 0xE0048: 84, + 0xE0049: 84, + 0xE004A: 84, + 0xE004B: 84, + 0xE004C: 84, + 0xE004D: 84, + 0xE004E: 84, + 0xE004F: 84, + 0xE0050: 84, + 0xE0051: 84, + 0xE0052: 84, + 0xE0053: 84, + 0xE0054: 84, + 0xE0055: 84, + 0xE0056: 84, + 0xE0057: 84, + 0xE0058: 84, + 0xE0059: 84, + 0xE005A: 84, + 0xE005B: 84, + 0xE005C: 84, + 0xE005D: 84, + 0xE005E: 84, + 0xE005F: 84, + 0xE0060: 84, + 0xE0061: 84, + 0xE0062: 84, + 0xE0063: 84, + 0xE0064: 84, + 0xE0065: 84, + 0xE0066: 84, + 0xE0067: 84, + 0xE0068: 84, + 0xE0069: 84, + 0xE006A: 84, + 0xE006B: 84, + 0xE006C: 84, + 0xE006D: 84, + 0xE006E: 84, + 0xE006F: 84, + 0xE0070: 84, + 0xE0071: 84, + 0xE0072: 84, + 0xE0073: 84, + 0xE0074: 84, + 0xE0075: 84, + 0xE0076: 84, + 0xE0077: 84, + 0xE0078: 84, + 0xE0079: 84, + 0xE007A: 84, + 0xE007B: 84, + 0xE007C: 84, + 0xE007D: 84, + 0xE007E: 84, + 0xE007F: 84, + 0xE0100: 84, + 0xE0101: 84, + 0xE0102: 84, + 0xE0103: 84, + 0xE0104: 84, + 0xE0105: 84, + 0xE0106: 84, + 0xE0107: 84, + 0xE0108: 84, + 0xE0109: 84, + 0xE010A: 84, + 0xE010B: 84, + 0xE010C: 84, + 0xE010D: 84, + 0xE010E: 84, + 0xE010F: 84, + 0xE0110: 84, + 0xE0111: 84, + 0xE0112: 84, + 0xE0113: 84, + 0xE0114: 84, + 0xE0115: 84, + 0xE0116: 84, + 0xE0117: 84, + 0xE0118: 84, + 0xE0119: 84, + 0xE011A: 84, + 0xE011B: 84, + 0xE011C: 84, + 0xE011D: 84, + 0xE011E: 84, + 0xE011F: 84, + 0xE0120: 84, + 0xE0121: 84, + 0xE0122: 84, + 0xE0123: 84, + 0xE0124: 84, + 0xE0125: 84, + 0xE0126: 84, + 0xE0127: 84, + 0xE0128: 84, + 0xE0129: 84, + 0xE012A: 84, + 0xE012B: 84, + 0xE012C: 84, + 0xE012D: 84, + 0xE012E: 84, + 0xE012F: 84, + 0xE0130: 84, + 0xE0131: 84, + 0xE0132: 84, + 0xE0133: 84, + 0xE0134: 84, + 0xE0135: 84, + 0xE0136: 84, + 0xE0137: 84, + 0xE0138: 84, + 0xE0139: 84, + 0xE013A: 84, + 0xE013B: 84, + 0xE013C: 84, + 0xE013D: 84, + 0xE013E: 84, + 0xE013F: 84, + 0xE0140: 84, + 0xE0141: 84, + 0xE0142: 84, + 0xE0143: 84, + 0xE0144: 84, + 0xE0145: 84, + 0xE0146: 84, + 0xE0147: 84, + 0xE0148: 84, + 0xE0149: 84, + 0xE014A: 84, + 0xE014B: 84, + 0xE014C: 84, + 0xE014D: 84, + 0xE014E: 84, + 0xE014F: 84, + 0xE0150: 84, + 0xE0151: 84, + 0xE0152: 84, + 0xE0153: 84, + 0xE0154: 84, + 0xE0155: 84, + 0xE0156: 84, + 0xE0157: 84, + 0xE0158: 84, + 0xE0159: 84, + 0xE015A: 84, + 0xE015B: 84, + 0xE015C: 84, + 0xE015D: 84, + 0xE015E: 84, + 0xE015F: 84, + 0xE0160: 84, + 0xE0161: 84, + 0xE0162: 84, + 0xE0163: 84, + 0xE0164: 84, + 0xE0165: 84, + 0xE0166: 84, + 0xE0167: 84, + 0xE0168: 84, + 0xE0169: 84, + 0xE016A: 84, + 0xE016B: 84, + 0xE016C: 84, + 0xE016D: 84, + 0xE016E: 84, + 0xE016F: 84, + 0xE0170: 84, + 0xE0171: 84, + 0xE0172: 84, + 0xE0173: 84, + 0xE0174: 84, + 0xE0175: 84, + 0xE0176: 84, + 0xE0177: 84, + 0xE0178: 84, + 0xE0179: 84, + 0xE017A: 84, + 0xE017B: 84, + 0xE017C: 84, + 0xE017D: 84, + 0xE017E: 84, + 0xE017F: 84, + 0xE0180: 84, + 0xE0181: 84, + 0xE0182: 84, + 0xE0183: 84, + 0xE0184: 84, + 0xE0185: 84, + 0xE0186: 84, + 0xE0187: 84, + 0xE0188: 84, + 0xE0189: 84, + 0xE018A: 84, + 0xE018B: 84, + 0xE018C: 84, + 0xE018D: 84, + 0xE018E: 84, + 0xE018F: 84, + 0xE0190: 84, + 0xE0191: 84, + 0xE0192: 84, + 0xE0193: 84, + 0xE0194: 84, + 0xE0195: 84, + 0xE0196: 84, + 0xE0197: 84, + 0xE0198: 84, + 0xE0199: 84, + 0xE019A: 84, + 0xE019B: 84, + 0xE019C: 84, + 0xE019D: 84, + 0xE019E: 84, + 0xE019F: 84, + 0xE01A0: 84, + 0xE01A1: 84, + 0xE01A2: 84, + 0xE01A3: 84, + 0xE01A4: 84, + 0xE01A5: 84, + 0xE01A6: 84, + 0xE01A7: 84, + 0xE01A8: 84, + 0xE01A9: 84, + 0xE01AA: 84, + 0xE01AB: 84, + 0xE01AC: 84, + 0xE01AD: 84, + 0xE01AE: 84, + 0xE01AF: 84, + 0xE01B0: 84, + 0xE01B1: 84, + 0xE01B2: 84, + 0xE01B3: 84, + 0xE01B4: 84, + 0xE01B5: 84, + 0xE01B6: 84, + 0xE01B7: 84, + 0xE01B8: 84, + 0xE01B9: 84, + 0xE01BA: 84, + 0xE01BB: 84, + 0xE01BC: 84, + 0xE01BD: 84, + 0xE01BE: 84, + 0xE01BF: 84, + 0xE01C0: 84, + 0xE01C1: 84, + 0xE01C2: 84, + 0xE01C3: 84, + 0xE01C4: 84, + 0xE01C5: 84, + 0xE01C6: 84, + 0xE01C7: 84, + 0xE01C8: 84, + 0xE01C9: 84, + 0xE01CA: 84, + 0xE01CB: 84, + 0xE01CC: 84, + 0xE01CD: 84, + 0xE01CE: 84, + 0xE01CF: 84, + 0xE01D0: 84, + 0xE01D1: 84, + 0xE01D2: 84, + 0xE01D3: 84, + 0xE01D4: 84, + 0xE01D5: 84, + 0xE01D6: 84, + 0xE01D7: 84, + 0xE01D8: 84, + 0xE01D9: 84, + 0xE01DA: 84, + 0xE01DB: 84, + 0xE01DC: 84, + 0xE01DD: 84, + 0xE01DE: 84, + 0xE01DF: 84, + 0xE01E0: 84, + 0xE01E1: 84, + 0xE01E2: 84, + 0xE01E3: 84, + 0xE01E4: 84, + 0xE01E5: 84, + 0xE01E6: 84, + 0xE01E7: 84, + 0xE01E8: 84, + 0xE01E9: 84, + 0xE01EA: 84, + 0xE01EB: 84, + 0xE01EC: 84, + 0xE01ED: 84, + 0xE01EE: 84, + 0xE01EF: 84, +} +codepoint_classes = { + "PVALID": ( + 0x2D0000002E, + 0x300000003A, + 0x610000007B, + 0xDF000000F7, + 0xF800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010A, + 0x10B0000010C, + 0x10D0000010E, + 0x10F00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011A, + 0x11B0000011C, + 0x11D0000011E, + 0x11F00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012A, + 0x12B0000012C, + 0x12D0000012E, + 0x12F00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13A0000013B, + 0x13C0000013D, + 0x13E0000013F, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14B0000014C, + 0x14D0000014E, + 0x14F00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015A, + 0x15B0000015C, + 0x15D0000015E, + 0x15F00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016A, + 0x16B0000016C, + 0x16D0000016E, + 0x16F00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17A0000017B, + 0x17C0000017D, + 0x17E0000017F, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18C0000018E, + 0x19200000193, + 0x19500000196, + 0x1990000019C, + 0x19E0000019F, + 0x1A1000001A2, + 0x1A3000001A4, + 0x1A5000001A6, + 0x1A8000001A9, + 0x1AA000001AC, + 0x1AD000001AE, + 0x1B0000001B1, + 0x1B4000001B5, + 0x1B6000001B7, + 0x1B9000001BC, + 0x1BD000001C4, + 0x1CE000001CF, + 0x1D0000001D1, + 0x1D2000001D3, + 0x1D4000001D5, + 0x1D6000001D7, + 0x1D8000001D9, + 0x1DA000001DB, + 0x1DC000001DE, + 0x1DF000001E0, + 0x1E1000001E2, + 0x1E3000001E4, + 0x1E5000001E6, + 0x1E7000001E8, + 0x1E9000001EA, + 0x1EB000001EC, + 0x1ED000001EE, + 0x1EF000001F1, + 0x1F5000001F6, + 0x1F9000001FA, + 0x1FB000001FC, + 0x1FD000001FE, + 0x1FF00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020A, + 0x20B0000020C, + 0x20D0000020E, + 0x20F00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021A, + 0x21B0000021C, + 0x21D0000021E, + 0x21F00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022A, + 0x22B0000022C, + 0x22D0000022E, + 0x22F00000230, + 0x23100000232, + 0x2330000023A, + 0x23C0000023D, + 0x23F00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024A, + 0x24B0000024C, + 0x24D0000024E, + 0x24F000002B0, + 0x2B9000002C2, + 0x2C6000002D2, + 0x2EC000002ED, + 0x2EE000002EF, + 0x30000000340, + 0x34200000343, + 0x3460000034F, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37B0000037E, + 0x39000000391, + 0x3AC000003CF, + 0x3D7000003D8, + 0x3D9000003DA, + 0x3DB000003DC, + 0x3DD000003DE, + 0x3DF000003E0, + 0x3E1000003E2, + 0x3E3000003E4, + 0x3E5000003E6, + 0x3E7000003E8, + 0x3E9000003EA, + 0x3EB000003EC, + 0x3ED000003EE, + 0x3EF000003F0, + 0x3F3000003F4, + 0x3F8000003F9, + 0x3FB000003FD, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046A, + 0x46B0000046C, + 0x46D0000046E, + 0x46F00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047A, + 0x47B0000047C, + 0x47D0000047E, + 0x47F00000480, + 0x48100000482, + 0x48300000488, + 0x48B0000048C, + 0x48D0000048E, + 0x48F00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049A, + 0x49B0000049C, + 0x49D0000049E, + 0x49F000004A0, + 0x4A1000004A2, + 0x4A3000004A4, + 0x4A5000004A6, + 0x4A7000004A8, + 0x4A9000004AA, + 0x4AB000004AC, + 0x4AD000004AE, + 0x4AF000004B0, + 0x4B1000004B2, + 0x4B3000004B4, + 0x4B5000004B6, + 0x4B7000004B8, + 0x4B9000004BA, + 0x4BB000004BC, + 0x4BD000004BE, + 0x4BF000004C0, + 0x4C2000004C3, + 0x4C4000004C5, + 0x4C6000004C7, + 0x4C8000004C9, + 0x4CA000004CB, + 0x4CC000004CD, + 0x4CE000004D0, + 0x4D1000004D2, + 0x4D3000004D4, + 0x4D5000004D6, + 0x4D7000004D8, + 0x4D9000004DA, + 0x4DB000004DC, + 0x4DD000004DE, + 0x4DF000004E0, + 0x4E1000004E2, + 0x4E3000004E4, + 0x4E5000004E6, + 0x4E7000004E8, + 0x4E9000004EA, + 0x4EB000004EC, + 0x4ED000004EE, + 0x4EF000004F0, + 0x4F1000004F2, + 0x4F3000004F4, + 0x4F5000004F6, + 0x4F7000004F8, + 0x4F9000004FA, + 0x4FB000004FC, + 0x4FD000004FE, + 0x4FF00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050A, + 0x50B0000050C, + 0x50D0000050E, + 0x50F00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051A, + 0x51B0000051C, + 0x51D0000051E, + 0x51F00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052A, + 0x52B0000052C, + 0x52D0000052E, + 0x52F00000530, + 0x5590000055A, + 0x56000000587, + 0x58800000589, + 0x591000005BE, + 0x5BF000005C0, + 0x5C1000005C3, + 0x5C4000005C6, + 0x5C7000005C8, + 0x5D0000005EB, + 0x5EF000005F3, + 0x6100000061B, + 0x62000000640, + 0x64100000660, + 0x66E00000675, + 0x679000006D4, + 0x6D5000006DD, + 0x6DF000006E9, + 0x6EA000006F0, + 0x6FA00000700, + 0x7100000074B, + 0x74D000007B2, + 0x7C0000007F6, + 0x7FD000007FE, + 0x8000000082E, + 0x8400000085C, + 0x8600000086B, + 0x87000000888, + 0x8890000088F, + 0x898000008E2, + 0x8E300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098D, + 0x98F00000991, + 0x993000009A9, + 0x9AA000009B1, + 0x9B2000009B3, + 0x9B6000009BA, + 0x9BC000009C5, + 0x9C7000009C9, + 0x9CB000009CF, + 0x9D7000009D8, + 0x9E0000009E4, + 0x9E6000009F2, + 0x9FC000009FD, + 0x9FE000009FF, + 0xA0100000A04, + 0xA0500000A0B, + 0xA0F00000A11, + 0xA1300000A29, + 0xA2A00000A31, + 0xA3200000A33, + 0xA3500000A36, + 0xA3800000A3A, + 0xA3C00000A3D, + 0xA3E00000A43, + 0xA4700000A49, + 0xA4B00000A4E, + 0xA5100000A52, + 0xA5C00000A5D, + 0xA6600000A76, + 0xA8100000A84, + 0xA8500000A8E, + 0xA8F00000A92, + 0xA9300000AA9, + 0xAAA00000AB1, + 0xAB200000AB4, + 0xAB500000ABA, + 0xABC00000AC6, + 0xAC700000ACA, + 0xACB00000ACE, + 0xAD000000AD1, + 0xAE000000AE4, + 0xAE600000AF0, + 0xAF900000B00, + 0xB0100000B04, + 0xB0500000B0D, + 0xB0F00000B11, + 0xB1300000B29, + 0xB2A00000B31, + 0xB3200000B34, + 0xB3500000B3A, + 0xB3C00000B45, + 0xB4700000B49, + 0xB4B00000B4E, + 0xB5500000B58, + 0xB5F00000B64, + 0xB6600000B70, + 0xB7100000B72, + 0xB8200000B84, + 0xB8500000B8B, + 0xB8E00000B91, + 0xB9200000B96, + 0xB9900000B9B, + 0xB9C00000B9D, + 0xB9E00000BA0, + 0xBA300000BA5, + 0xBA800000BAB, + 0xBAE00000BBA, + 0xBBE00000BC3, + 0xBC600000BC9, + 0xBCA00000BCE, + 0xBD000000BD1, + 0xBD700000BD8, + 0xBE600000BF0, + 0xC0000000C0D, + 0xC0E00000C11, + 0xC1200000C29, + 0xC2A00000C3A, + 0xC3C00000C45, + 0xC4600000C49, + 0xC4A00000C4E, + 0xC5500000C57, + 0xC5800000C5B, + 0xC5D00000C5E, + 0xC6000000C64, + 0xC6600000C70, + 0xC8000000C84, + 0xC8500000C8D, + 0xC8E00000C91, + 0xC9200000CA9, + 0xCAA00000CB4, + 0xCB500000CBA, + 0xCBC00000CC5, + 0xCC600000CC9, + 0xCCA00000CCE, + 0xCD500000CD7, + 0xCDD00000CDF, + 0xCE000000CE4, + 0xCE600000CF0, + 0xCF100000CF4, + 0xD0000000D0D, + 0xD0E00000D11, + 0xD1200000D45, + 0xD4600000D49, + 0xD4A00000D4F, + 0xD5400000D58, + 0xD5F00000D64, + 0xD6600000D70, + 0xD7A00000D80, + 0xD8100000D84, + 0xD8500000D97, + 0xD9A00000DB2, + 0xDB300000DBC, + 0xDBD00000DBE, + 0xDC000000DC7, + 0xDCA00000DCB, + 0xDCF00000DD5, + 0xDD600000DD7, + 0xDD800000DE0, + 0xDE600000DF0, + 0xDF200000DF4, + 0xE0100000E33, + 0xE3400000E3B, + 0xE4000000E4F, + 0xE5000000E5A, + 0xE8100000E83, + 0xE8400000E85, + 0xE8600000E8B, + 0xE8C00000EA4, + 0xEA500000EA6, + 0xEA700000EB3, + 0xEB400000EBE, + 0xEC000000EC5, + 0xEC600000EC7, + 0xEC800000ECF, + 0xED000000EDA, + 0xEDE00000EE0, + 0xF0000000F01, + 0xF0B00000F0C, + 0xF1800000F1A, + 0xF2000000F2A, + 0xF3500000F36, + 0xF3700000F38, + 0xF3900000F3A, + 0xF3E00000F43, + 0xF4400000F48, + 0xF4900000F4D, + 0xF4E00000F52, + 0xF5300000F57, + 0xF5800000F5C, + 0xF5D00000F69, + 0xF6A00000F6D, + 0xF7100000F73, + 0xF7400000F75, + 0xF7A00000F81, + 0xF8200000F85, + 0xF8600000F93, + 0xF9400000F98, + 0xF9900000F9D, + 0xF9E00000FA2, + 0xFA300000FA7, + 0xFA800000FAC, + 0xFAD00000FB9, + 0xFBA00000FBD, + 0xFC600000FC7, + 0x10000000104A, + 0x10500000109E, + 0x10D0000010FB, + 0x10FD00001100, + 0x120000001249, + 0x124A0000124E, + 0x125000001257, + 0x125800001259, + 0x125A0000125E, + 0x126000001289, + 0x128A0000128E, + 0x1290000012B1, + 0x12B2000012B6, + 0x12B8000012BF, + 0x12C0000012C1, + 0x12C2000012C6, + 0x12C8000012D7, + 0x12D800001311, + 0x131200001316, + 0x13180000135B, + 0x135D00001360, + 0x138000001390, + 0x13A0000013F6, + 0x14010000166D, + 0x166F00001680, + 0x16810000169B, + 0x16A0000016EB, + 0x16F1000016F9, + 0x170000001716, + 0x171F00001735, + 0x174000001754, + 0x17600000176D, + 0x176E00001771, + 0x177200001774, + 0x1780000017B4, + 0x17B6000017D4, + 0x17D7000017D8, + 0x17DC000017DE, + 0x17E0000017EA, + 0x18100000181A, + 0x182000001879, + 0x1880000018AB, + 0x18B0000018F6, + 0x19000000191F, + 0x19200000192C, + 0x19300000193C, + 0x19460000196E, + 0x197000001975, + 0x1980000019AC, + 0x19B0000019CA, + 0x19D0000019DA, + 0x1A0000001A1C, + 0x1A2000001A5F, + 0x1A6000001A7D, + 0x1A7F00001A8A, + 0x1A9000001A9A, + 0x1AA700001AA8, + 0x1AB000001ABE, + 0x1ABF00001ACF, + 0x1B0000001B4D, + 0x1B5000001B5A, + 0x1B6B00001B74, + 0x1B8000001BF4, + 0x1C0000001C38, + 0x1C4000001C4A, + 0x1C4D00001C7E, + 0x1CD000001CD3, + 0x1CD400001CFB, + 0x1D0000001D2C, + 0x1D2F00001D30, + 0x1D3B00001D3C, + 0x1D4E00001D4F, + 0x1D6B00001D78, + 0x1D7900001D9B, + 0x1DC000001E00, + 0x1E0100001E02, + 0x1E0300001E04, + 0x1E0500001E06, + 0x1E0700001E08, + 0x1E0900001E0A, + 0x1E0B00001E0C, + 0x1E0D00001E0E, + 0x1E0F00001E10, + 0x1E1100001E12, + 0x1E1300001E14, + 0x1E1500001E16, + 0x1E1700001E18, + 0x1E1900001E1A, + 0x1E1B00001E1C, + 0x1E1D00001E1E, + 0x1E1F00001E20, + 0x1E2100001E22, + 0x1E2300001E24, + 0x1E2500001E26, + 0x1E2700001E28, + 0x1E2900001E2A, + 0x1E2B00001E2C, + 0x1E2D00001E2E, + 0x1E2F00001E30, + 0x1E3100001E32, + 0x1E3300001E34, + 0x1E3500001E36, + 0x1E3700001E38, + 0x1E3900001E3A, + 0x1E3B00001E3C, + 0x1E3D00001E3E, + 0x1E3F00001E40, + 0x1E4100001E42, + 0x1E4300001E44, + 0x1E4500001E46, + 0x1E4700001E48, + 0x1E4900001E4A, + 0x1E4B00001E4C, + 0x1E4D00001E4E, + 0x1E4F00001E50, + 0x1E5100001E52, + 0x1E5300001E54, + 0x1E5500001E56, + 0x1E5700001E58, + 0x1E5900001E5A, + 0x1E5B00001E5C, + 0x1E5D00001E5E, + 0x1E5F00001E60, + 0x1E6100001E62, + 0x1E6300001E64, + 0x1E6500001E66, + 0x1E6700001E68, + 0x1E6900001E6A, + 0x1E6B00001E6C, + 0x1E6D00001E6E, + 0x1E6F00001E70, + 0x1E7100001E72, + 0x1E7300001E74, + 0x1E7500001E76, + 0x1E7700001E78, + 0x1E7900001E7A, + 0x1E7B00001E7C, + 0x1E7D00001E7E, + 0x1E7F00001E80, + 0x1E8100001E82, + 0x1E8300001E84, + 0x1E8500001E86, + 0x1E8700001E88, + 0x1E8900001E8A, + 0x1E8B00001E8C, + 0x1E8D00001E8E, + 0x1E8F00001E90, + 0x1E9100001E92, + 0x1E9300001E94, + 0x1E9500001E9A, + 0x1E9C00001E9E, + 0x1E9F00001EA0, + 0x1EA100001EA2, + 0x1EA300001EA4, + 0x1EA500001EA6, + 0x1EA700001EA8, + 0x1EA900001EAA, + 0x1EAB00001EAC, + 0x1EAD00001EAE, + 0x1EAF00001EB0, + 0x1EB100001EB2, + 0x1EB300001EB4, + 0x1EB500001EB6, + 0x1EB700001EB8, + 0x1EB900001EBA, + 0x1EBB00001EBC, + 0x1EBD00001EBE, + 0x1EBF00001EC0, + 0x1EC100001EC2, + 0x1EC300001EC4, + 0x1EC500001EC6, + 0x1EC700001EC8, + 0x1EC900001ECA, + 0x1ECB00001ECC, + 0x1ECD00001ECE, + 0x1ECF00001ED0, + 0x1ED100001ED2, + 0x1ED300001ED4, + 0x1ED500001ED6, + 0x1ED700001ED8, + 0x1ED900001EDA, + 0x1EDB00001EDC, + 0x1EDD00001EDE, + 0x1EDF00001EE0, + 0x1EE100001EE2, + 0x1EE300001EE4, + 0x1EE500001EE6, + 0x1EE700001EE8, + 0x1EE900001EEA, + 0x1EEB00001EEC, + 0x1EED00001EEE, + 0x1EEF00001EF0, + 0x1EF100001EF2, + 0x1EF300001EF4, + 0x1EF500001EF6, + 0x1EF700001EF8, + 0x1EF900001EFA, + 0x1EFB00001EFC, + 0x1EFD00001EFE, + 0x1EFF00001F08, + 0x1F1000001F16, + 0x1F2000001F28, + 0x1F3000001F38, + 0x1F4000001F46, + 0x1F5000001F58, + 0x1F6000001F68, + 0x1F7000001F71, + 0x1F7200001F73, + 0x1F7400001F75, + 0x1F7600001F77, + 0x1F7800001F79, + 0x1F7A00001F7B, + 0x1F7C00001F7D, + 0x1FB000001FB2, + 0x1FB600001FB7, + 0x1FC600001FC7, + 0x1FD000001FD3, + 0x1FD600001FD8, + 0x1FE000001FE3, + 0x1FE400001FE8, + 0x1FF600001FF7, + 0x214E0000214F, + 0x218400002185, + 0x2C3000002C60, + 0x2C6100002C62, + 0x2C6500002C67, + 0x2C6800002C69, + 0x2C6A00002C6B, + 0x2C6C00002C6D, + 0x2C7100002C72, + 0x2C7300002C75, + 0x2C7600002C7C, + 0x2C8100002C82, + 0x2C8300002C84, + 0x2C8500002C86, + 0x2C8700002C88, + 0x2C8900002C8A, + 0x2C8B00002C8C, + 0x2C8D00002C8E, + 0x2C8F00002C90, + 0x2C9100002C92, + 0x2C9300002C94, + 0x2C9500002C96, + 0x2C9700002C98, + 0x2C9900002C9A, + 0x2C9B00002C9C, + 0x2C9D00002C9E, + 0x2C9F00002CA0, + 0x2CA100002CA2, + 0x2CA300002CA4, + 0x2CA500002CA6, + 0x2CA700002CA8, + 0x2CA900002CAA, + 0x2CAB00002CAC, + 0x2CAD00002CAE, + 0x2CAF00002CB0, + 0x2CB100002CB2, + 0x2CB300002CB4, + 0x2CB500002CB6, + 0x2CB700002CB8, + 0x2CB900002CBA, + 0x2CBB00002CBC, + 0x2CBD00002CBE, + 0x2CBF00002CC0, + 0x2CC100002CC2, + 0x2CC300002CC4, + 0x2CC500002CC6, + 0x2CC700002CC8, + 0x2CC900002CCA, + 0x2CCB00002CCC, + 0x2CCD00002CCE, + 0x2CCF00002CD0, + 0x2CD100002CD2, + 0x2CD300002CD4, + 0x2CD500002CD6, + 0x2CD700002CD8, + 0x2CD900002CDA, + 0x2CDB00002CDC, + 0x2CDD00002CDE, + 0x2CDF00002CE0, + 0x2CE100002CE2, + 0x2CE300002CE5, + 0x2CEC00002CED, + 0x2CEE00002CF2, + 0x2CF300002CF4, + 0x2D0000002D26, + 0x2D2700002D28, + 0x2D2D00002D2E, + 0x2D3000002D68, + 0x2D7F00002D97, + 0x2DA000002DA7, + 0x2DA800002DAF, + 0x2DB000002DB7, + 0x2DB800002DBF, + 0x2DC000002DC7, + 0x2DC800002DCF, + 0x2DD000002DD7, + 0x2DD800002DDF, + 0x2DE000002E00, + 0x2E2F00002E30, + 0x300500003008, + 0x302A0000302E, + 0x303C0000303D, + 0x304100003097, + 0x30990000309B, + 0x309D0000309F, + 0x30A1000030FB, + 0x30FC000030FF, + 0x310500003130, + 0x31A0000031C0, + 0x31F000003200, + 0x340000004DC0, + 0x4E000000A48D, + 0xA4D00000A4FE, + 0xA5000000A60D, + 0xA6100000A62C, + 0xA6410000A642, + 0xA6430000A644, + 0xA6450000A646, + 0xA6470000A648, + 0xA6490000A64A, + 0xA64B0000A64C, + 0xA64D0000A64E, + 0xA64F0000A650, + 0xA6510000A652, + 0xA6530000A654, + 0xA6550000A656, + 0xA6570000A658, + 0xA6590000A65A, + 0xA65B0000A65C, + 0xA65D0000A65E, + 0xA65F0000A660, + 0xA6610000A662, + 0xA6630000A664, + 0xA6650000A666, + 0xA6670000A668, + 0xA6690000A66A, + 0xA66B0000A66C, + 0xA66D0000A670, + 0xA6740000A67E, + 0xA67F0000A680, + 0xA6810000A682, + 0xA6830000A684, + 0xA6850000A686, + 0xA6870000A688, + 0xA6890000A68A, + 0xA68B0000A68C, + 0xA68D0000A68E, + 0xA68F0000A690, + 0xA6910000A692, + 0xA6930000A694, + 0xA6950000A696, + 0xA6970000A698, + 0xA6990000A69A, + 0xA69B0000A69C, + 0xA69E0000A6E6, + 0xA6F00000A6F2, + 0xA7170000A720, + 0xA7230000A724, + 0xA7250000A726, + 0xA7270000A728, + 0xA7290000A72A, + 0xA72B0000A72C, + 0xA72D0000A72E, + 0xA72F0000A732, + 0xA7330000A734, + 0xA7350000A736, + 0xA7370000A738, + 0xA7390000A73A, + 0xA73B0000A73C, + 0xA73D0000A73E, + 0xA73F0000A740, + 0xA7410000A742, + 0xA7430000A744, + 0xA7450000A746, + 0xA7470000A748, + 0xA7490000A74A, + 0xA74B0000A74C, + 0xA74D0000A74E, + 0xA74F0000A750, + 0xA7510000A752, + 0xA7530000A754, + 0xA7550000A756, + 0xA7570000A758, + 0xA7590000A75A, + 0xA75B0000A75C, + 0xA75D0000A75E, + 0xA75F0000A760, + 0xA7610000A762, + 0xA7630000A764, + 0xA7650000A766, + 0xA7670000A768, + 0xA7690000A76A, + 0xA76B0000A76C, + 0xA76D0000A76E, + 0xA76F0000A770, + 0xA7710000A779, + 0xA77A0000A77B, + 0xA77C0000A77D, + 0xA77F0000A780, + 0xA7810000A782, + 0xA7830000A784, + 0xA7850000A786, + 0xA7870000A789, + 0xA78C0000A78D, + 0xA78E0000A790, + 0xA7910000A792, + 0xA7930000A796, + 0xA7970000A798, + 0xA7990000A79A, + 0xA79B0000A79C, + 0xA79D0000A79E, + 0xA79F0000A7A0, + 0xA7A10000A7A2, + 0xA7A30000A7A4, + 0xA7A50000A7A6, + 0xA7A70000A7A8, + 0xA7A90000A7AA, + 0xA7AF0000A7B0, + 0xA7B50000A7B6, + 0xA7B70000A7B8, + 0xA7B90000A7BA, + 0xA7BB0000A7BC, + 0xA7BD0000A7BE, + 0xA7BF0000A7C0, + 0xA7C10000A7C2, + 0xA7C30000A7C4, + 0xA7C80000A7C9, + 0xA7CA0000A7CB, + 0xA7D10000A7D2, + 0xA7D30000A7D4, + 0xA7D50000A7D6, + 0xA7D70000A7D8, + 0xA7D90000A7DA, + 0xA7F60000A7F8, + 0xA7FA0000A828, + 0xA82C0000A82D, + 0xA8400000A874, + 0xA8800000A8C6, + 0xA8D00000A8DA, + 0xA8E00000A8F8, + 0xA8FB0000A8FC, + 0xA8FD0000A92E, + 0xA9300000A954, + 0xA9800000A9C1, + 0xA9CF0000A9DA, + 0xA9E00000A9FF, + 0xAA000000AA37, + 0xAA400000AA4E, + 0xAA500000AA5A, + 0xAA600000AA77, + 0xAA7A0000AAC3, + 0xAADB0000AADE, + 0xAAE00000AAF0, + 0xAAF20000AAF7, + 0xAB010000AB07, + 0xAB090000AB0F, + 0xAB110000AB17, + 0xAB200000AB27, + 0xAB280000AB2F, + 0xAB300000AB5B, + 0xAB600000AB69, + 0xABC00000ABEB, + 0xABEC0000ABEE, + 0xABF00000ABFA, + 0xAC000000D7A4, + 0xFA0E0000FA10, + 0xFA110000FA12, + 0xFA130000FA15, + 0xFA1F0000FA20, + 0xFA210000FA22, + 0xFA230000FA25, + 0xFA270000FA2A, + 0xFB1E0000FB1F, + 0xFE200000FE30, + 0xFE730000FE74, + 0x100000001000C, + 0x1000D00010027, + 0x100280001003B, + 0x1003C0001003E, + 0x1003F0001004E, + 0x100500001005E, + 0x10080000100FB, + 0x101FD000101FE, + 0x102800001029D, + 0x102A0000102D1, + 0x102E0000102E1, + 0x1030000010320, + 0x1032D00010341, + 0x103420001034A, + 0x103500001037B, + 0x103800001039E, + 0x103A0000103C4, + 0x103C8000103D0, + 0x104280001049E, + 0x104A0000104AA, + 0x104D8000104FC, + 0x1050000010528, + 0x1053000010564, + 0x10597000105A2, + 0x105A3000105B2, + 0x105B3000105BA, + 0x105BB000105BD, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1078000010781, + 0x1080000010806, + 0x1080800010809, + 0x1080A00010836, + 0x1083700010839, + 0x1083C0001083D, + 0x1083F00010856, + 0x1086000010877, + 0x108800001089F, + 0x108E0000108F3, + 0x108F4000108F6, + 0x1090000010916, + 0x109200001093A, + 0x10980000109B8, + 0x109BE000109C0, + 0x10A0000010A04, + 0x10A0500010A07, + 0x10A0C00010A14, + 0x10A1500010A18, + 0x10A1900010A36, + 0x10A3800010A3B, + 0x10A3F00010A40, + 0x10A6000010A7D, + 0x10A8000010A9D, + 0x10AC000010AC8, + 0x10AC900010AE7, + 0x10B0000010B36, + 0x10B4000010B56, + 0x10B6000010B73, + 0x10B8000010B92, + 0x10C0000010C49, + 0x10CC000010CF3, + 0x10D0000010D28, + 0x10D3000010D3A, + 0x10E8000010EAA, + 0x10EAB00010EAD, + 0x10EB000010EB2, + 0x10EFD00010F1D, + 0x10F2700010F28, + 0x10F3000010F51, + 0x10F7000010F86, + 0x10FB000010FC5, + 0x10FE000010FF7, + 0x1100000011047, + 0x1106600011076, + 0x1107F000110BB, + 0x110C2000110C3, + 0x110D0000110E9, + 0x110F0000110FA, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111C5, + 0x111C9000111CD, + 0x111CE000111DB, + 0x111DC000111DD, + 0x1120000011212, + 0x1121300011238, + 0x1123E00011242, + 0x1128000011287, + 0x1128800011289, + 0x1128A0001128E, + 0x1128F0001129E, + 0x1129F000112A9, + 0x112B0000112EB, + 0x112F0000112FA, + 0x1130000011304, + 0x113050001130D, + 0x1130F00011311, + 0x1131300011329, + 0x1132A00011331, + 0x1133200011334, + 0x113350001133A, + 0x1133B00011345, + 0x1134700011349, + 0x1134B0001134E, + 0x1135000011351, + 0x1135700011358, + 0x1135D00011364, + 0x113660001136D, + 0x1137000011375, + 0x114000001144B, + 0x114500001145A, + 0x1145E00011462, + 0x11480000114C6, + 0x114C7000114C8, + 0x114D0000114DA, + 0x11580000115B6, + 0x115B8000115C1, + 0x115D8000115DE, + 0x1160000011641, + 0x1164400011645, + 0x116500001165A, + 0x11680000116B9, + 0x116C0000116CA, + 0x117000001171B, + 0x1171D0001172C, + 0x117300001173A, + 0x1174000011747, + 0x118000001183B, + 0x118C0000118EA, + 0x118FF00011907, + 0x119090001190A, + 0x1190C00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193B00011944, + 0x119500001195A, + 0x119A0000119A8, + 0x119AA000119D8, + 0x119DA000119E2, + 0x119E3000119E5, + 0x11A0000011A3F, + 0x11A4700011A48, + 0x11A5000011A9A, + 0x11A9D00011A9E, + 0x11AB000011AF9, + 0x11C0000011C09, + 0x11C0A00011C37, + 0x11C3800011C41, + 0x11C5000011C5A, + 0x11C7200011C90, + 0x11C9200011CA8, + 0x11CA900011CB7, + 0x11D0000011D07, + 0x11D0800011D0A, + 0x11D0B00011D37, + 0x11D3A00011D3B, + 0x11D3C00011D3E, + 0x11D3F00011D48, + 0x11D5000011D5A, + 0x11D6000011D66, + 0x11D6700011D69, + 0x11D6A00011D8F, + 0x11D9000011D92, + 0x11D9300011D99, + 0x11DA000011DAA, + 0x11EE000011EF7, + 0x11F0000011F11, + 0x11F1200011F3B, + 0x11F3E00011F43, + 0x11F5000011F5A, + 0x11FB000011FB1, + 0x120000001239A, + 0x1248000012544, + 0x12F9000012FF1, + 0x1300000013430, + 0x1344000013456, + 0x1440000014647, + 0x1680000016A39, + 0x16A4000016A5F, + 0x16A6000016A6A, + 0x16A7000016ABF, + 0x16AC000016ACA, + 0x16AD000016AEE, + 0x16AF000016AF5, + 0x16B0000016B37, + 0x16B4000016B44, + 0x16B5000016B5A, + 0x16B6300016B78, + 0x16B7D00016B90, + 0x16E6000016E80, + 0x16F0000016F4B, + 0x16F4F00016F88, + 0x16F8F00016FA0, + 0x16FE000016FE2, + 0x16FE300016FE5, + 0x16FF000016FF2, + 0x17000000187F8, + 0x1880000018CD6, + 0x18D0000018D09, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B123, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1B1550001B156, + 0x1B1640001B168, + 0x1B1700001B2FC, + 0x1BC000001BC6B, + 0x1BC700001BC7D, + 0x1BC800001BC89, + 0x1BC900001BC9A, + 0x1BC9D0001BC9F, + 0x1CF000001CF2E, + 0x1CF300001CF47, + 0x1DA000001DA37, + 0x1DA3B0001DA6D, + 0x1DA750001DA76, + 0x1DA840001DA85, + 0x1DA9B0001DAA0, + 0x1DAA10001DAB0, + 0x1DF000001DF1F, + 0x1DF250001DF2B, + 0x1E0000001E007, + 0x1E0080001E019, + 0x1E01B0001E022, + 0x1E0230001E025, + 0x1E0260001E02B, + 0x1E08F0001E090, + 0x1E1000001E12D, + 0x1E1300001E13E, + 0x1E1400001E14A, + 0x1E14E0001E14F, + 0x1E2900001E2AF, + 0x1E2C00001E2FA, + 0x1E4D00001E4FA, + 0x1E7E00001E7E7, + 0x1E7E80001E7EC, + 0x1E7ED0001E7EF, + 0x1E7F00001E7FF, + 0x1E8000001E8C5, + 0x1E8D00001E8D7, + 0x1E9220001E94C, + 0x1E9500001E95A, + 0x200000002A6E0, + 0x2A7000002B73A, + 0x2B7400002B81E, + 0x2B8200002CEA2, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x300000003134B, + 0x31350000323B0, + ), + "CONTEXTJ": (0x200C0000200E,), + "CONTEXTO": ( + 0xB7000000B8, + 0x37500000376, + 0x5F3000005F5, + 0x6600000066A, + 0x6F0000006FA, + 0x30FB000030FC, + ), +} diff --git a/venv/lib/python3.11/site-packages/idna/intranges.py b/venv/lib/python3.11/site-packages/idna/intranges.py new file mode 100644 index 0000000..7bfaa8d --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/intranges.py @@ -0,0 +1,57 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect +from typing import List, Tuple + + +def intranges_from_list(list_: List[int]) -> Tuple[int, ...]: + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i + 1 < len(sorted_list): + if sorted_list[i] == sorted_list[i + 1] - 1: + continue + current_range = sorted_list[last_write + 1 : i + 1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + + +def _encode_range(start: int, end: int) -> int: + return (start << 32) | end + + +def _decode_range(r: int) -> Tuple[int, int]: + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool: + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos - 1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/venv/lib/python3.11/site-packages/idna/package_data.py b/venv/lib/python3.11/site-packages/idna/package_data.py new file mode 100644 index 0000000..514ff7e --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/package_data.py @@ -0,0 +1 @@ +__version__ = "3.10" diff --git a/venv/lib/python3.11/site-packages/idna/py.typed b/venv/lib/python3.11/site-packages/idna/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/idna/uts46data.py b/venv/lib/python3.11/site-packages/idna/uts46data.py new file mode 100644 index 0000000..eb89432 --- /dev/null +++ b/venv/lib/python3.11/site-packages/idna/uts46data.py @@ -0,0 +1,8681 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +from typing import List, Tuple, Union + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "15.1.0" + + +def _seg_0() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x0, "3"), + (0x1, "3"), + (0x2, "3"), + (0x3, "3"), + (0x4, "3"), + (0x5, "3"), + (0x6, "3"), + (0x7, "3"), + (0x8, "3"), + (0x9, "3"), + (0xA, "3"), + (0xB, "3"), + (0xC, "3"), + (0xD, "3"), + (0xE, "3"), + (0xF, "3"), + (0x10, "3"), + (0x11, "3"), + (0x12, "3"), + (0x13, "3"), + (0x14, "3"), + (0x15, "3"), + (0x16, "3"), + (0x17, "3"), + (0x18, "3"), + (0x19, "3"), + (0x1A, "3"), + (0x1B, "3"), + (0x1C, "3"), + (0x1D, "3"), + (0x1E, "3"), + (0x1F, "3"), + (0x20, "3"), + (0x21, "3"), + (0x22, "3"), + (0x23, "3"), + (0x24, "3"), + (0x25, "3"), + (0x26, "3"), + (0x27, "3"), + (0x28, "3"), + (0x29, "3"), + (0x2A, "3"), + (0x2B, "3"), + (0x2C, "3"), + (0x2D, "V"), + (0x2E, "V"), + (0x2F, "3"), + (0x30, "V"), + (0x31, "V"), + (0x32, "V"), + (0x33, "V"), + (0x34, "V"), + (0x35, "V"), + (0x36, "V"), + (0x37, "V"), + (0x38, "V"), + (0x39, "V"), + (0x3A, "3"), + (0x3B, "3"), + (0x3C, "3"), + (0x3D, "3"), + (0x3E, "3"), + (0x3F, "3"), + (0x40, "3"), + (0x41, "M", "a"), + (0x42, "M", "b"), + (0x43, "M", "c"), + (0x44, "M", "d"), + (0x45, "M", "e"), + (0x46, "M", "f"), + (0x47, "M", "g"), + (0x48, "M", "h"), + (0x49, "M", "i"), + (0x4A, "M", "j"), + (0x4B, "M", "k"), + (0x4C, "M", "l"), + (0x4D, "M", "m"), + (0x4E, "M", "n"), + (0x4F, "M", "o"), + (0x50, "M", "p"), + (0x51, "M", "q"), + (0x52, "M", "r"), + (0x53, "M", "s"), + (0x54, "M", "t"), + (0x55, "M", "u"), + (0x56, "M", "v"), + (0x57, "M", "w"), + (0x58, "M", "x"), + (0x59, "M", "y"), + (0x5A, "M", "z"), + (0x5B, "3"), + (0x5C, "3"), + (0x5D, "3"), + (0x5E, "3"), + (0x5F, "3"), + (0x60, "3"), + (0x61, "V"), + (0x62, "V"), + (0x63, "V"), + ] + + +def _seg_1() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x64, "V"), + (0x65, "V"), + (0x66, "V"), + (0x67, "V"), + (0x68, "V"), + (0x69, "V"), + (0x6A, "V"), + (0x6B, "V"), + (0x6C, "V"), + (0x6D, "V"), + (0x6E, "V"), + (0x6F, "V"), + (0x70, "V"), + (0x71, "V"), + (0x72, "V"), + (0x73, "V"), + (0x74, "V"), + (0x75, "V"), + (0x76, "V"), + (0x77, "V"), + (0x78, "V"), + (0x79, "V"), + (0x7A, "V"), + (0x7B, "3"), + (0x7C, "3"), + (0x7D, "3"), + (0x7E, "3"), + (0x7F, "3"), + (0x80, "X"), + (0x81, "X"), + (0x82, "X"), + (0x83, "X"), + (0x84, "X"), + (0x85, "X"), + (0x86, "X"), + (0x87, "X"), + (0x88, "X"), + (0x89, "X"), + (0x8A, "X"), + (0x8B, "X"), + (0x8C, "X"), + (0x8D, "X"), + (0x8E, "X"), + (0x8F, "X"), + (0x90, "X"), + (0x91, "X"), + (0x92, "X"), + (0x93, "X"), + (0x94, "X"), + (0x95, "X"), + (0x96, "X"), + (0x97, "X"), + (0x98, "X"), + (0x99, "X"), + (0x9A, "X"), + (0x9B, "X"), + (0x9C, "X"), + (0x9D, "X"), + (0x9E, "X"), + (0x9F, "X"), + (0xA0, "3", " "), + (0xA1, "V"), + (0xA2, "V"), + (0xA3, "V"), + (0xA4, "V"), + (0xA5, "V"), + (0xA6, "V"), + (0xA7, "V"), + (0xA8, "3", " ̈"), + (0xA9, "V"), + (0xAA, "M", "a"), + (0xAB, "V"), + (0xAC, "V"), + (0xAD, "I"), + (0xAE, "V"), + (0xAF, "3", " ̄"), + (0xB0, "V"), + (0xB1, "V"), + (0xB2, "M", "2"), + (0xB3, "M", "3"), + (0xB4, "3", " ́"), + (0xB5, "M", "μ"), + (0xB6, "V"), + (0xB7, "V"), + (0xB8, "3", " ̧"), + (0xB9, "M", "1"), + (0xBA, "M", "o"), + (0xBB, "V"), + (0xBC, "M", "1⁄4"), + (0xBD, "M", "1⁄2"), + (0xBE, "M", "3⁄4"), + (0xBF, "V"), + (0xC0, "M", "à"), + (0xC1, "M", "á"), + (0xC2, "M", "â"), + (0xC3, "M", "ã"), + (0xC4, "M", "ä"), + (0xC5, "M", "å"), + (0xC6, "M", "æ"), + (0xC7, "M", "ç"), + ] + + +def _seg_2() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xC8, "M", "è"), + (0xC9, "M", "é"), + (0xCA, "M", "ê"), + (0xCB, "M", "ë"), + (0xCC, "M", "ì"), + (0xCD, "M", "í"), + (0xCE, "M", "î"), + (0xCF, "M", "ï"), + (0xD0, "M", "ð"), + (0xD1, "M", "ñ"), + (0xD2, "M", "ò"), + (0xD3, "M", "ó"), + (0xD4, "M", "ô"), + (0xD5, "M", "õ"), + (0xD6, "M", "ö"), + (0xD7, "V"), + (0xD8, "M", "ø"), + (0xD9, "M", "ù"), + (0xDA, "M", "ú"), + (0xDB, "M", "û"), + (0xDC, "M", "ü"), + (0xDD, "M", "ý"), + (0xDE, "M", "þ"), + (0xDF, "D", "ss"), + (0xE0, "V"), + (0xE1, "V"), + (0xE2, "V"), + (0xE3, "V"), + (0xE4, "V"), + (0xE5, "V"), + (0xE6, "V"), + (0xE7, "V"), + (0xE8, "V"), + (0xE9, "V"), + (0xEA, "V"), + (0xEB, "V"), + (0xEC, "V"), + (0xED, "V"), + (0xEE, "V"), + (0xEF, "V"), + (0xF0, "V"), + (0xF1, "V"), + (0xF2, "V"), + (0xF3, "V"), + (0xF4, "V"), + (0xF5, "V"), + (0xF6, "V"), + (0xF7, "V"), + (0xF8, "V"), + (0xF9, "V"), + (0xFA, "V"), + (0xFB, "V"), + (0xFC, "V"), + (0xFD, "V"), + (0xFE, "V"), + (0xFF, "V"), + (0x100, "M", "ā"), + (0x101, "V"), + (0x102, "M", "ă"), + (0x103, "V"), + (0x104, "M", "ą"), + (0x105, "V"), + (0x106, "M", "ć"), + (0x107, "V"), + (0x108, "M", "ĉ"), + (0x109, "V"), + (0x10A, "M", "ċ"), + (0x10B, "V"), + (0x10C, "M", "č"), + (0x10D, "V"), + (0x10E, "M", "ď"), + (0x10F, "V"), + (0x110, "M", "đ"), + (0x111, "V"), + (0x112, "M", "ē"), + (0x113, "V"), + (0x114, "M", "ĕ"), + (0x115, "V"), + (0x116, "M", "ė"), + (0x117, "V"), + (0x118, "M", "ę"), + (0x119, "V"), + (0x11A, "M", "ě"), + (0x11B, "V"), + (0x11C, "M", "ĝ"), + (0x11D, "V"), + (0x11E, "M", "ğ"), + (0x11F, "V"), + (0x120, "M", "ġ"), + (0x121, "V"), + (0x122, "M", "ģ"), + (0x123, "V"), + (0x124, "M", "ĥ"), + (0x125, "V"), + (0x126, "M", "ħ"), + (0x127, "V"), + (0x128, "M", "ĩ"), + (0x129, "V"), + (0x12A, "M", "ī"), + (0x12B, "V"), + ] + + +def _seg_3() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x12C, "M", "ĭ"), + (0x12D, "V"), + (0x12E, "M", "į"), + (0x12F, "V"), + (0x130, "M", "i̇"), + (0x131, "V"), + (0x132, "M", "ij"), + (0x134, "M", "ĵ"), + (0x135, "V"), + (0x136, "M", "ķ"), + (0x137, "V"), + (0x139, "M", "ĺ"), + (0x13A, "V"), + (0x13B, "M", "ļ"), + (0x13C, "V"), + (0x13D, "M", "ľ"), + (0x13E, "V"), + (0x13F, "M", "l·"), + (0x141, "M", "ł"), + (0x142, "V"), + (0x143, "M", "ń"), + (0x144, "V"), + (0x145, "M", "ņ"), + (0x146, "V"), + (0x147, "M", "ň"), + (0x148, "V"), + (0x149, "M", "ʼn"), + (0x14A, "M", "ŋ"), + (0x14B, "V"), + (0x14C, "M", "ō"), + (0x14D, "V"), + (0x14E, "M", "ŏ"), + (0x14F, "V"), + (0x150, "M", "ő"), + (0x151, "V"), + (0x152, "M", "œ"), + (0x153, "V"), + (0x154, "M", "ŕ"), + (0x155, "V"), + (0x156, "M", "ŗ"), + (0x157, "V"), + (0x158, "M", "ř"), + (0x159, "V"), + (0x15A, "M", "ś"), + (0x15B, "V"), + (0x15C, "M", "ŝ"), + (0x15D, "V"), + (0x15E, "M", "ş"), + (0x15F, "V"), + (0x160, "M", "š"), + (0x161, "V"), + (0x162, "M", "ţ"), + (0x163, "V"), + (0x164, "M", "ť"), + (0x165, "V"), + (0x166, "M", "ŧ"), + (0x167, "V"), + (0x168, "M", "ũ"), + (0x169, "V"), + (0x16A, "M", "ū"), + (0x16B, "V"), + (0x16C, "M", "ŭ"), + (0x16D, "V"), + (0x16E, "M", "ů"), + (0x16F, "V"), + (0x170, "M", "ű"), + (0x171, "V"), + (0x172, "M", "ų"), + (0x173, "V"), + (0x174, "M", "ŵ"), + (0x175, "V"), + (0x176, "M", "ŷ"), + (0x177, "V"), + (0x178, "M", "ÿ"), + (0x179, "M", "ź"), + (0x17A, "V"), + (0x17B, "M", "ż"), + (0x17C, "V"), + (0x17D, "M", "ž"), + (0x17E, "V"), + (0x17F, "M", "s"), + (0x180, "V"), + (0x181, "M", "ɓ"), + (0x182, "M", "ƃ"), + (0x183, "V"), + (0x184, "M", "ƅ"), + (0x185, "V"), + (0x186, "M", "ɔ"), + (0x187, "M", "ƈ"), + (0x188, "V"), + (0x189, "M", "ɖ"), + (0x18A, "M", "ɗ"), + (0x18B, "M", "ƌ"), + (0x18C, "V"), + (0x18E, "M", "ǝ"), + (0x18F, "M", "ə"), + (0x190, "M", "ɛ"), + (0x191, "M", "ƒ"), + (0x192, "V"), + (0x193, "M", "ɠ"), + ] + + +def _seg_4() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x194, "M", "ɣ"), + (0x195, "V"), + (0x196, "M", "ɩ"), + (0x197, "M", "ɨ"), + (0x198, "M", "ƙ"), + (0x199, "V"), + (0x19C, "M", "ɯ"), + (0x19D, "M", "ɲ"), + (0x19E, "V"), + (0x19F, "M", "ɵ"), + (0x1A0, "M", "ơ"), + (0x1A1, "V"), + (0x1A2, "M", "ƣ"), + (0x1A3, "V"), + (0x1A4, "M", "ƥ"), + (0x1A5, "V"), + (0x1A6, "M", "ʀ"), + (0x1A7, "M", "ƨ"), + (0x1A8, "V"), + (0x1A9, "M", "ʃ"), + (0x1AA, "V"), + (0x1AC, "M", "ƭ"), + (0x1AD, "V"), + (0x1AE, "M", "ʈ"), + (0x1AF, "M", "ư"), + (0x1B0, "V"), + (0x1B1, "M", "ʊ"), + (0x1B2, "M", "ʋ"), + (0x1B3, "M", "ƴ"), + (0x1B4, "V"), + (0x1B5, "M", "ƶ"), + (0x1B6, "V"), + (0x1B7, "M", "ʒ"), + (0x1B8, "M", "ƹ"), + (0x1B9, "V"), + (0x1BC, "M", "ƽ"), + (0x1BD, "V"), + (0x1C4, "M", "dž"), + (0x1C7, "M", "lj"), + (0x1CA, "M", "nj"), + (0x1CD, "M", "ǎ"), + (0x1CE, "V"), + (0x1CF, "M", "ǐ"), + (0x1D0, "V"), + (0x1D1, "M", "ǒ"), + (0x1D2, "V"), + (0x1D3, "M", "ǔ"), + (0x1D4, "V"), + (0x1D5, "M", "ǖ"), + (0x1D6, "V"), + (0x1D7, "M", "ǘ"), + (0x1D8, "V"), + (0x1D9, "M", "ǚ"), + (0x1DA, "V"), + (0x1DB, "M", "ǜ"), + (0x1DC, "V"), + (0x1DE, "M", "ǟ"), + (0x1DF, "V"), + (0x1E0, "M", "ǡ"), + (0x1E1, "V"), + (0x1E2, "M", "ǣ"), + (0x1E3, "V"), + (0x1E4, "M", "ǥ"), + (0x1E5, "V"), + (0x1E6, "M", "ǧ"), + (0x1E7, "V"), + (0x1E8, "M", "ǩ"), + (0x1E9, "V"), + (0x1EA, "M", "ǫ"), + (0x1EB, "V"), + (0x1EC, "M", "ǭ"), + (0x1ED, "V"), + (0x1EE, "M", "ǯ"), + (0x1EF, "V"), + (0x1F1, "M", "dz"), + (0x1F4, "M", "ǵ"), + (0x1F5, "V"), + (0x1F6, "M", "ƕ"), + (0x1F7, "M", "ƿ"), + (0x1F8, "M", "ǹ"), + (0x1F9, "V"), + (0x1FA, "M", "ǻ"), + (0x1FB, "V"), + (0x1FC, "M", "ǽ"), + (0x1FD, "V"), + (0x1FE, "M", "ǿ"), + (0x1FF, "V"), + (0x200, "M", "ȁ"), + (0x201, "V"), + (0x202, "M", "ȃ"), + (0x203, "V"), + (0x204, "M", "ȅ"), + (0x205, "V"), + (0x206, "M", "ȇ"), + (0x207, "V"), + (0x208, "M", "ȉ"), + (0x209, "V"), + (0x20A, "M", "ȋ"), + (0x20B, "V"), + (0x20C, "M", "ȍ"), + ] + + +def _seg_5() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x20D, "V"), + (0x20E, "M", "ȏ"), + (0x20F, "V"), + (0x210, "M", "ȑ"), + (0x211, "V"), + (0x212, "M", "ȓ"), + (0x213, "V"), + (0x214, "M", "ȕ"), + (0x215, "V"), + (0x216, "M", "ȗ"), + (0x217, "V"), + (0x218, "M", "ș"), + (0x219, "V"), + (0x21A, "M", "ț"), + (0x21B, "V"), + (0x21C, "M", "ȝ"), + (0x21D, "V"), + (0x21E, "M", "ȟ"), + (0x21F, "V"), + (0x220, "M", "ƞ"), + (0x221, "V"), + (0x222, "M", "ȣ"), + (0x223, "V"), + (0x224, "M", "ȥ"), + (0x225, "V"), + (0x226, "M", "ȧ"), + (0x227, "V"), + (0x228, "M", "ȩ"), + (0x229, "V"), + (0x22A, "M", "ȫ"), + (0x22B, "V"), + (0x22C, "M", "ȭ"), + (0x22D, "V"), + (0x22E, "M", "ȯ"), + (0x22F, "V"), + (0x230, "M", "ȱ"), + (0x231, "V"), + (0x232, "M", "ȳ"), + (0x233, "V"), + (0x23A, "M", "ⱥ"), + (0x23B, "M", "ȼ"), + (0x23C, "V"), + (0x23D, "M", "ƚ"), + (0x23E, "M", "ⱦ"), + (0x23F, "V"), + (0x241, "M", "ɂ"), + (0x242, "V"), + (0x243, "M", "ƀ"), + (0x244, "M", "ʉ"), + (0x245, "M", "ʌ"), + (0x246, "M", "ɇ"), + (0x247, "V"), + (0x248, "M", "ɉ"), + (0x249, "V"), + (0x24A, "M", "ɋ"), + (0x24B, "V"), + (0x24C, "M", "ɍ"), + (0x24D, "V"), + (0x24E, "M", "ɏ"), + (0x24F, "V"), + (0x2B0, "M", "h"), + (0x2B1, "M", "ɦ"), + (0x2B2, "M", "j"), + (0x2B3, "M", "r"), + (0x2B4, "M", "ɹ"), + (0x2B5, "M", "ɻ"), + (0x2B6, "M", "ʁ"), + (0x2B7, "M", "w"), + (0x2B8, "M", "y"), + (0x2B9, "V"), + (0x2D8, "3", " ̆"), + (0x2D9, "3", " ̇"), + (0x2DA, "3", " ̊"), + (0x2DB, "3", " ̨"), + (0x2DC, "3", " ̃"), + (0x2DD, "3", " ̋"), + (0x2DE, "V"), + (0x2E0, "M", "ɣ"), + (0x2E1, "M", "l"), + (0x2E2, "M", "s"), + (0x2E3, "M", "x"), + (0x2E4, "M", "ʕ"), + (0x2E5, "V"), + (0x340, "M", "̀"), + (0x341, "M", "́"), + (0x342, "V"), + (0x343, "M", "̓"), + (0x344, "M", "̈́"), + (0x345, "M", "ι"), + (0x346, "V"), + (0x34F, "I"), + (0x350, "V"), + (0x370, "M", "ͱ"), + (0x371, "V"), + (0x372, "M", "ͳ"), + (0x373, "V"), + (0x374, "M", "ʹ"), + (0x375, "V"), + (0x376, "M", "ͷ"), + (0x377, "V"), + ] + + +def _seg_6() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x378, "X"), + (0x37A, "3", " ι"), + (0x37B, "V"), + (0x37E, "3", ";"), + (0x37F, "M", "ϳ"), + (0x380, "X"), + (0x384, "3", " ́"), + (0x385, "3", " ̈́"), + (0x386, "M", "ά"), + (0x387, "M", "·"), + (0x388, "M", "έ"), + (0x389, "M", "ή"), + (0x38A, "M", "ί"), + (0x38B, "X"), + (0x38C, "M", "ό"), + (0x38D, "X"), + (0x38E, "M", "ύ"), + (0x38F, "M", "ώ"), + (0x390, "V"), + (0x391, "M", "α"), + (0x392, "M", "β"), + (0x393, "M", "γ"), + (0x394, "M", "δ"), + (0x395, "M", "ε"), + (0x396, "M", "ζ"), + (0x397, "M", "η"), + (0x398, "M", "θ"), + (0x399, "M", "ι"), + (0x39A, "M", "κ"), + (0x39B, "M", "λ"), + (0x39C, "M", "μ"), + (0x39D, "M", "ν"), + (0x39E, "M", "ξ"), + (0x39F, "M", "ο"), + (0x3A0, "M", "π"), + (0x3A1, "M", "ρ"), + (0x3A2, "X"), + (0x3A3, "M", "σ"), + (0x3A4, "M", "τ"), + (0x3A5, "M", "υ"), + (0x3A6, "M", "φ"), + (0x3A7, "M", "χ"), + (0x3A8, "M", "ψ"), + (0x3A9, "M", "ω"), + (0x3AA, "M", "ϊ"), + (0x3AB, "M", "ϋ"), + (0x3AC, "V"), + (0x3C2, "D", "σ"), + (0x3C3, "V"), + (0x3CF, "M", "ϗ"), + (0x3D0, "M", "β"), + (0x3D1, "M", "θ"), + (0x3D2, "M", "υ"), + (0x3D3, "M", "ύ"), + (0x3D4, "M", "ϋ"), + (0x3D5, "M", "φ"), + (0x3D6, "M", "π"), + (0x3D7, "V"), + (0x3D8, "M", "ϙ"), + (0x3D9, "V"), + (0x3DA, "M", "ϛ"), + (0x3DB, "V"), + (0x3DC, "M", "ϝ"), + (0x3DD, "V"), + (0x3DE, "M", "ϟ"), + (0x3DF, "V"), + (0x3E0, "M", "ϡ"), + (0x3E1, "V"), + (0x3E2, "M", "ϣ"), + (0x3E3, "V"), + (0x3E4, "M", "ϥ"), + (0x3E5, "V"), + (0x3E6, "M", "ϧ"), + (0x3E7, "V"), + (0x3E8, "M", "ϩ"), + (0x3E9, "V"), + (0x3EA, "M", "ϫ"), + (0x3EB, "V"), + (0x3EC, "M", "ϭ"), + (0x3ED, "V"), + (0x3EE, "M", "ϯ"), + (0x3EF, "V"), + (0x3F0, "M", "κ"), + (0x3F1, "M", "ρ"), + (0x3F2, "M", "σ"), + (0x3F3, "V"), + (0x3F4, "M", "θ"), + (0x3F5, "M", "ε"), + (0x3F6, "V"), + (0x3F7, "M", "ϸ"), + (0x3F8, "V"), + (0x3F9, "M", "σ"), + (0x3FA, "M", "ϻ"), + (0x3FB, "V"), + (0x3FD, "M", "ͻ"), + (0x3FE, "M", "ͼ"), + (0x3FF, "M", "ͽ"), + (0x400, "M", "ѐ"), + (0x401, "M", "ё"), + (0x402, "M", "ђ"), + ] + + +def _seg_7() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x403, "M", "ѓ"), + (0x404, "M", "є"), + (0x405, "M", "ѕ"), + (0x406, "M", "і"), + (0x407, "M", "ї"), + (0x408, "M", "ј"), + (0x409, "M", "љ"), + (0x40A, "M", "њ"), + (0x40B, "M", "ћ"), + (0x40C, "M", "ќ"), + (0x40D, "M", "ѝ"), + (0x40E, "M", "ў"), + (0x40F, "M", "џ"), + (0x410, "M", "а"), + (0x411, "M", "б"), + (0x412, "M", "в"), + (0x413, "M", "г"), + (0x414, "M", "д"), + (0x415, "M", "е"), + (0x416, "M", "ж"), + (0x417, "M", "з"), + (0x418, "M", "и"), + (0x419, "M", "й"), + (0x41A, "M", "к"), + (0x41B, "M", "л"), + (0x41C, "M", "м"), + (0x41D, "M", "н"), + (0x41E, "M", "о"), + (0x41F, "M", "п"), + (0x420, "M", "р"), + (0x421, "M", "с"), + (0x422, "M", "т"), + (0x423, "M", "у"), + (0x424, "M", "ф"), + (0x425, "M", "х"), + (0x426, "M", "ц"), + (0x427, "M", "ч"), + (0x428, "M", "ш"), + (0x429, "M", "щ"), + (0x42A, "M", "ъ"), + (0x42B, "M", "ы"), + (0x42C, "M", "ь"), + (0x42D, "M", "э"), + (0x42E, "M", "ю"), + (0x42F, "M", "я"), + (0x430, "V"), + (0x460, "M", "ѡ"), + (0x461, "V"), + (0x462, "M", "ѣ"), + (0x463, "V"), + (0x464, "M", "ѥ"), + (0x465, "V"), + (0x466, "M", "ѧ"), + (0x467, "V"), + (0x468, "M", "ѩ"), + (0x469, "V"), + (0x46A, "M", "ѫ"), + (0x46B, "V"), + (0x46C, "M", "ѭ"), + (0x46D, "V"), + (0x46E, "M", "ѯ"), + (0x46F, "V"), + (0x470, "M", "ѱ"), + (0x471, "V"), + (0x472, "M", "ѳ"), + (0x473, "V"), + (0x474, "M", "ѵ"), + (0x475, "V"), + (0x476, "M", "ѷ"), + (0x477, "V"), + (0x478, "M", "ѹ"), + (0x479, "V"), + (0x47A, "M", "ѻ"), + (0x47B, "V"), + (0x47C, "M", "ѽ"), + (0x47D, "V"), + (0x47E, "M", "ѿ"), + (0x47F, "V"), + (0x480, "M", "ҁ"), + (0x481, "V"), + (0x48A, "M", "ҋ"), + (0x48B, "V"), + (0x48C, "M", "ҍ"), + (0x48D, "V"), + (0x48E, "M", "ҏ"), + (0x48F, "V"), + (0x490, "M", "ґ"), + (0x491, "V"), + (0x492, "M", "ғ"), + (0x493, "V"), + (0x494, "M", "ҕ"), + (0x495, "V"), + (0x496, "M", "җ"), + (0x497, "V"), + (0x498, "M", "ҙ"), + (0x499, "V"), + (0x49A, "M", "қ"), + (0x49B, "V"), + (0x49C, "M", "ҝ"), + (0x49D, "V"), + ] + + +def _seg_8() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x49E, "M", "ҟ"), + (0x49F, "V"), + (0x4A0, "M", "ҡ"), + (0x4A1, "V"), + (0x4A2, "M", "ң"), + (0x4A3, "V"), + (0x4A4, "M", "ҥ"), + (0x4A5, "V"), + (0x4A6, "M", "ҧ"), + (0x4A7, "V"), + (0x4A8, "M", "ҩ"), + (0x4A9, "V"), + (0x4AA, "M", "ҫ"), + (0x4AB, "V"), + (0x4AC, "M", "ҭ"), + (0x4AD, "V"), + (0x4AE, "M", "ү"), + (0x4AF, "V"), + (0x4B0, "M", "ұ"), + (0x4B1, "V"), + (0x4B2, "M", "ҳ"), + (0x4B3, "V"), + (0x4B4, "M", "ҵ"), + (0x4B5, "V"), + (0x4B6, "M", "ҷ"), + (0x4B7, "V"), + (0x4B8, "M", "ҹ"), + (0x4B9, "V"), + (0x4BA, "M", "һ"), + (0x4BB, "V"), + (0x4BC, "M", "ҽ"), + (0x4BD, "V"), + (0x4BE, "M", "ҿ"), + (0x4BF, "V"), + (0x4C0, "X"), + (0x4C1, "M", "ӂ"), + (0x4C2, "V"), + (0x4C3, "M", "ӄ"), + (0x4C4, "V"), + (0x4C5, "M", "ӆ"), + (0x4C6, "V"), + (0x4C7, "M", "ӈ"), + (0x4C8, "V"), + (0x4C9, "M", "ӊ"), + (0x4CA, "V"), + (0x4CB, "M", "ӌ"), + (0x4CC, "V"), + (0x4CD, "M", "ӎ"), + (0x4CE, "V"), + (0x4D0, "M", "ӑ"), + (0x4D1, "V"), + (0x4D2, "M", "ӓ"), + (0x4D3, "V"), + (0x4D4, "M", "ӕ"), + (0x4D5, "V"), + (0x4D6, "M", "ӗ"), + (0x4D7, "V"), + (0x4D8, "M", "ә"), + (0x4D9, "V"), + (0x4DA, "M", "ӛ"), + (0x4DB, "V"), + (0x4DC, "M", "ӝ"), + (0x4DD, "V"), + (0x4DE, "M", "ӟ"), + (0x4DF, "V"), + (0x4E0, "M", "ӡ"), + (0x4E1, "V"), + (0x4E2, "M", "ӣ"), + (0x4E3, "V"), + (0x4E4, "M", "ӥ"), + (0x4E5, "V"), + (0x4E6, "M", "ӧ"), + (0x4E7, "V"), + (0x4E8, "M", "ө"), + (0x4E9, "V"), + (0x4EA, "M", "ӫ"), + (0x4EB, "V"), + (0x4EC, "M", "ӭ"), + (0x4ED, "V"), + (0x4EE, "M", "ӯ"), + (0x4EF, "V"), + (0x4F0, "M", "ӱ"), + (0x4F1, "V"), + (0x4F2, "M", "ӳ"), + (0x4F3, "V"), + (0x4F4, "M", "ӵ"), + (0x4F5, "V"), + (0x4F6, "M", "ӷ"), + (0x4F7, "V"), + (0x4F8, "M", "ӹ"), + (0x4F9, "V"), + (0x4FA, "M", "ӻ"), + (0x4FB, "V"), + (0x4FC, "M", "ӽ"), + (0x4FD, "V"), + (0x4FE, "M", "ӿ"), + (0x4FF, "V"), + (0x500, "M", "ԁ"), + (0x501, "V"), + (0x502, "M", "ԃ"), + ] + + +def _seg_9() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x503, "V"), + (0x504, "M", "ԅ"), + (0x505, "V"), + (0x506, "M", "ԇ"), + (0x507, "V"), + (0x508, "M", "ԉ"), + (0x509, "V"), + (0x50A, "M", "ԋ"), + (0x50B, "V"), + (0x50C, "M", "ԍ"), + (0x50D, "V"), + (0x50E, "M", "ԏ"), + (0x50F, "V"), + (0x510, "M", "ԑ"), + (0x511, "V"), + (0x512, "M", "ԓ"), + (0x513, "V"), + (0x514, "M", "ԕ"), + (0x515, "V"), + (0x516, "M", "ԗ"), + (0x517, "V"), + (0x518, "M", "ԙ"), + (0x519, "V"), + (0x51A, "M", "ԛ"), + (0x51B, "V"), + (0x51C, "M", "ԝ"), + (0x51D, "V"), + (0x51E, "M", "ԟ"), + (0x51F, "V"), + (0x520, "M", "ԡ"), + (0x521, "V"), + (0x522, "M", "ԣ"), + (0x523, "V"), + (0x524, "M", "ԥ"), + (0x525, "V"), + (0x526, "M", "ԧ"), + (0x527, "V"), + (0x528, "M", "ԩ"), + (0x529, "V"), + (0x52A, "M", "ԫ"), + (0x52B, "V"), + (0x52C, "M", "ԭ"), + (0x52D, "V"), + (0x52E, "M", "ԯ"), + (0x52F, "V"), + (0x530, "X"), + (0x531, "M", "ա"), + (0x532, "M", "բ"), + (0x533, "M", "գ"), + (0x534, "M", "դ"), + (0x535, "M", "ե"), + (0x536, "M", "զ"), + (0x537, "M", "է"), + (0x538, "M", "ը"), + (0x539, "M", "թ"), + (0x53A, "M", "ժ"), + (0x53B, "M", "ի"), + (0x53C, "M", "լ"), + (0x53D, "M", "խ"), + (0x53E, "M", "ծ"), + (0x53F, "M", "կ"), + (0x540, "M", "հ"), + (0x541, "M", "ձ"), + (0x542, "M", "ղ"), + (0x543, "M", "ճ"), + (0x544, "M", "մ"), + (0x545, "M", "յ"), + (0x546, "M", "ն"), + (0x547, "M", "շ"), + (0x548, "M", "ո"), + (0x549, "M", "չ"), + (0x54A, "M", "պ"), + (0x54B, "M", "ջ"), + (0x54C, "M", "ռ"), + (0x54D, "M", "ս"), + (0x54E, "M", "վ"), + (0x54F, "M", "տ"), + (0x550, "M", "ր"), + (0x551, "M", "ց"), + (0x552, "M", "ւ"), + (0x553, "M", "փ"), + (0x554, "M", "ք"), + (0x555, "M", "օ"), + (0x556, "M", "ֆ"), + (0x557, "X"), + (0x559, "V"), + (0x587, "M", "եւ"), + (0x588, "V"), + (0x58B, "X"), + (0x58D, "V"), + (0x590, "X"), + (0x591, "V"), + (0x5C8, "X"), + (0x5D0, "V"), + (0x5EB, "X"), + (0x5EF, "V"), + (0x5F5, "X"), + (0x606, "V"), + (0x61C, "X"), + (0x61D, "V"), + ] + + +def _seg_10() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x675, "M", "اٴ"), + (0x676, "M", "وٴ"), + (0x677, "M", "ۇٴ"), + (0x678, "M", "يٴ"), + (0x679, "V"), + (0x6DD, "X"), + (0x6DE, "V"), + (0x70E, "X"), + (0x710, "V"), + (0x74B, "X"), + (0x74D, "V"), + (0x7B2, "X"), + (0x7C0, "V"), + (0x7FB, "X"), + (0x7FD, "V"), + (0x82E, "X"), + (0x830, "V"), + (0x83F, "X"), + (0x840, "V"), + (0x85C, "X"), + (0x85E, "V"), + (0x85F, "X"), + (0x860, "V"), + (0x86B, "X"), + (0x870, "V"), + (0x88F, "X"), + (0x898, "V"), + (0x8E2, "X"), + (0x8E3, "V"), + (0x958, "M", "क़"), + (0x959, "M", "ख़"), + (0x95A, "M", "ग़"), + (0x95B, "M", "ज़"), + (0x95C, "M", "ड़"), + (0x95D, "M", "ढ़"), + (0x95E, "M", "फ़"), + (0x95F, "M", "य़"), + (0x960, "V"), + (0x984, "X"), + (0x985, "V"), + (0x98D, "X"), + (0x98F, "V"), + (0x991, "X"), + (0x993, "V"), + (0x9A9, "X"), + (0x9AA, "V"), + (0x9B1, "X"), + (0x9B2, "V"), + (0x9B3, "X"), + (0x9B6, "V"), + (0x9BA, "X"), + (0x9BC, "V"), + (0x9C5, "X"), + (0x9C7, "V"), + (0x9C9, "X"), + (0x9CB, "V"), + (0x9CF, "X"), + (0x9D7, "V"), + (0x9D8, "X"), + (0x9DC, "M", "ড়"), + (0x9DD, "M", "ঢ়"), + (0x9DE, "X"), + (0x9DF, "M", "য়"), + (0x9E0, "V"), + (0x9E4, "X"), + (0x9E6, "V"), + (0x9FF, "X"), + (0xA01, "V"), + (0xA04, "X"), + (0xA05, "V"), + (0xA0B, "X"), + (0xA0F, "V"), + (0xA11, "X"), + (0xA13, "V"), + (0xA29, "X"), + (0xA2A, "V"), + (0xA31, "X"), + (0xA32, "V"), + (0xA33, "M", "ਲ਼"), + (0xA34, "X"), + (0xA35, "V"), + (0xA36, "M", "ਸ਼"), + (0xA37, "X"), + (0xA38, "V"), + (0xA3A, "X"), + (0xA3C, "V"), + (0xA3D, "X"), + (0xA3E, "V"), + (0xA43, "X"), + (0xA47, "V"), + (0xA49, "X"), + (0xA4B, "V"), + (0xA4E, "X"), + (0xA51, "V"), + (0xA52, "X"), + (0xA59, "M", "ਖ਼"), + (0xA5A, "M", "ਗ਼"), + (0xA5B, "M", "ਜ਼"), + (0xA5C, "V"), + (0xA5D, "X"), + ] + + +def _seg_11() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA5E, "M", "ਫ਼"), + (0xA5F, "X"), + (0xA66, "V"), + (0xA77, "X"), + (0xA81, "V"), + (0xA84, "X"), + (0xA85, "V"), + (0xA8E, "X"), + (0xA8F, "V"), + (0xA92, "X"), + (0xA93, "V"), + (0xAA9, "X"), + (0xAAA, "V"), + (0xAB1, "X"), + (0xAB2, "V"), + (0xAB4, "X"), + (0xAB5, "V"), + (0xABA, "X"), + (0xABC, "V"), + (0xAC6, "X"), + (0xAC7, "V"), + (0xACA, "X"), + (0xACB, "V"), + (0xACE, "X"), + (0xAD0, "V"), + (0xAD1, "X"), + (0xAE0, "V"), + (0xAE4, "X"), + (0xAE6, "V"), + (0xAF2, "X"), + (0xAF9, "V"), + (0xB00, "X"), + (0xB01, "V"), + (0xB04, "X"), + (0xB05, "V"), + (0xB0D, "X"), + (0xB0F, "V"), + (0xB11, "X"), + (0xB13, "V"), + (0xB29, "X"), + (0xB2A, "V"), + (0xB31, "X"), + (0xB32, "V"), + (0xB34, "X"), + (0xB35, "V"), + (0xB3A, "X"), + (0xB3C, "V"), + (0xB45, "X"), + (0xB47, "V"), + (0xB49, "X"), + (0xB4B, "V"), + (0xB4E, "X"), + (0xB55, "V"), + (0xB58, "X"), + (0xB5C, "M", "ଡ଼"), + (0xB5D, "M", "ଢ଼"), + (0xB5E, "X"), + (0xB5F, "V"), + (0xB64, "X"), + (0xB66, "V"), + (0xB78, "X"), + (0xB82, "V"), + (0xB84, "X"), + (0xB85, "V"), + (0xB8B, "X"), + (0xB8E, "V"), + (0xB91, "X"), + (0xB92, "V"), + (0xB96, "X"), + (0xB99, "V"), + (0xB9B, "X"), + (0xB9C, "V"), + (0xB9D, "X"), + (0xB9E, "V"), + (0xBA0, "X"), + (0xBA3, "V"), + (0xBA5, "X"), + (0xBA8, "V"), + (0xBAB, "X"), + (0xBAE, "V"), + (0xBBA, "X"), + (0xBBE, "V"), + (0xBC3, "X"), + (0xBC6, "V"), + (0xBC9, "X"), + (0xBCA, "V"), + (0xBCE, "X"), + (0xBD0, "V"), + (0xBD1, "X"), + (0xBD7, "V"), + (0xBD8, "X"), + (0xBE6, "V"), + (0xBFB, "X"), + (0xC00, "V"), + (0xC0D, "X"), + (0xC0E, "V"), + (0xC11, "X"), + (0xC12, "V"), + (0xC29, "X"), + (0xC2A, "V"), + ] + + +def _seg_12() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xC3A, "X"), + (0xC3C, "V"), + (0xC45, "X"), + (0xC46, "V"), + (0xC49, "X"), + (0xC4A, "V"), + (0xC4E, "X"), + (0xC55, "V"), + (0xC57, "X"), + (0xC58, "V"), + (0xC5B, "X"), + (0xC5D, "V"), + (0xC5E, "X"), + (0xC60, "V"), + (0xC64, "X"), + (0xC66, "V"), + (0xC70, "X"), + (0xC77, "V"), + (0xC8D, "X"), + (0xC8E, "V"), + (0xC91, "X"), + (0xC92, "V"), + (0xCA9, "X"), + (0xCAA, "V"), + (0xCB4, "X"), + (0xCB5, "V"), + (0xCBA, "X"), + (0xCBC, "V"), + (0xCC5, "X"), + (0xCC6, "V"), + (0xCC9, "X"), + (0xCCA, "V"), + (0xCCE, "X"), + (0xCD5, "V"), + (0xCD7, "X"), + (0xCDD, "V"), + (0xCDF, "X"), + (0xCE0, "V"), + (0xCE4, "X"), + (0xCE6, "V"), + (0xCF0, "X"), + (0xCF1, "V"), + (0xCF4, "X"), + (0xD00, "V"), + (0xD0D, "X"), + (0xD0E, "V"), + (0xD11, "X"), + (0xD12, "V"), + (0xD45, "X"), + (0xD46, "V"), + (0xD49, "X"), + (0xD4A, "V"), + (0xD50, "X"), + (0xD54, "V"), + (0xD64, "X"), + (0xD66, "V"), + (0xD80, "X"), + (0xD81, "V"), + (0xD84, "X"), + (0xD85, "V"), + (0xD97, "X"), + (0xD9A, "V"), + (0xDB2, "X"), + (0xDB3, "V"), + (0xDBC, "X"), + (0xDBD, "V"), + (0xDBE, "X"), + (0xDC0, "V"), + (0xDC7, "X"), + (0xDCA, "V"), + (0xDCB, "X"), + (0xDCF, "V"), + (0xDD5, "X"), + (0xDD6, "V"), + (0xDD7, "X"), + (0xDD8, "V"), + (0xDE0, "X"), + (0xDE6, "V"), + (0xDF0, "X"), + (0xDF2, "V"), + (0xDF5, "X"), + (0xE01, "V"), + (0xE33, "M", "ํา"), + (0xE34, "V"), + (0xE3B, "X"), + (0xE3F, "V"), + (0xE5C, "X"), + (0xE81, "V"), + (0xE83, "X"), + (0xE84, "V"), + (0xE85, "X"), + (0xE86, "V"), + (0xE8B, "X"), + (0xE8C, "V"), + (0xEA4, "X"), + (0xEA5, "V"), + (0xEA6, "X"), + (0xEA7, "V"), + (0xEB3, "M", "ໍາ"), + (0xEB4, "V"), + ] + + +def _seg_13() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xEBE, "X"), + (0xEC0, "V"), + (0xEC5, "X"), + (0xEC6, "V"), + (0xEC7, "X"), + (0xEC8, "V"), + (0xECF, "X"), + (0xED0, "V"), + (0xEDA, "X"), + (0xEDC, "M", "ຫນ"), + (0xEDD, "M", "ຫມ"), + (0xEDE, "V"), + (0xEE0, "X"), + (0xF00, "V"), + (0xF0C, "M", "་"), + (0xF0D, "V"), + (0xF43, "M", "གྷ"), + (0xF44, "V"), + (0xF48, "X"), + (0xF49, "V"), + (0xF4D, "M", "ཌྷ"), + (0xF4E, "V"), + (0xF52, "M", "དྷ"), + (0xF53, "V"), + (0xF57, "M", "བྷ"), + (0xF58, "V"), + (0xF5C, "M", "ཛྷ"), + (0xF5D, "V"), + (0xF69, "M", "ཀྵ"), + (0xF6A, "V"), + (0xF6D, "X"), + (0xF71, "V"), + (0xF73, "M", "ཱི"), + (0xF74, "V"), + (0xF75, "M", "ཱུ"), + (0xF76, "M", "ྲྀ"), + (0xF77, "M", "ྲཱྀ"), + (0xF78, "M", "ླྀ"), + (0xF79, "M", "ླཱྀ"), + (0xF7A, "V"), + (0xF81, "M", "ཱྀ"), + (0xF82, "V"), + (0xF93, "M", "ྒྷ"), + (0xF94, "V"), + (0xF98, "X"), + (0xF99, "V"), + (0xF9D, "M", "ྜྷ"), + (0xF9E, "V"), + (0xFA2, "M", "ྡྷ"), + (0xFA3, "V"), + (0xFA7, "M", "ྦྷ"), + (0xFA8, "V"), + (0xFAC, "M", "ྫྷ"), + (0xFAD, "V"), + (0xFB9, "M", "ྐྵ"), + (0xFBA, "V"), + (0xFBD, "X"), + (0xFBE, "V"), + (0xFCD, "X"), + (0xFCE, "V"), + (0xFDB, "X"), + (0x1000, "V"), + (0x10A0, "X"), + (0x10C7, "M", "ⴧ"), + (0x10C8, "X"), + (0x10CD, "M", "ⴭ"), + (0x10CE, "X"), + (0x10D0, "V"), + (0x10FC, "M", "ნ"), + (0x10FD, "V"), + (0x115F, "X"), + (0x1161, "V"), + (0x1249, "X"), + (0x124A, "V"), + (0x124E, "X"), + (0x1250, "V"), + (0x1257, "X"), + (0x1258, "V"), + (0x1259, "X"), + (0x125A, "V"), + (0x125E, "X"), + (0x1260, "V"), + (0x1289, "X"), + (0x128A, "V"), + (0x128E, "X"), + (0x1290, "V"), + (0x12B1, "X"), + (0x12B2, "V"), + (0x12B6, "X"), + (0x12B8, "V"), + (0x12BF, "X"), + (0x12C0, "V"), + (0x12C1, "X"), + (0x12C2, "V"), + (0x12C6, "X"), + (0x12C8, "V"), + (0x12D7, "X"), + (0x12D8, "V"), + (0x1311, "X"), + (0x1312, "V"), + ] + + +def _seg_14() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1316, "X"), + (0x1318, "V"), + (0x135B, "X"), + (0x135D, "V"), + (0x137D, "X"), + (0x1380, "V"), + (0x139A, "X"), + (0x13A0, "V"), + (0x13F6, "X"), + (0x13F8, "M", "Ᏸ"), + (0x13F9, "M", "Ᏹ"), + (0x13FA, "M", "Ᏺ"), + (0x13FB, "M", "Ᏻ"), + (0x13FC, "M", "Ᏼ"), + (0x13FD, "M", "Ᏽ"), + (0x13FE, "X"), + (0x1400, "V"), + (0x1680, "X"), + (0x1681, "V"), + (0x169D, "X"), + (0x16A0, "V"), + (0x16F9, "X"), + (0x1700, "V"), + (0x1716, "X"), + (0x171F, "V"), + (0x1737, "X"), + (0x1740, "V"), + (0x1754, "X"), + (0x1760, "V"), + (0x176D, "X"), + (0x176E, "V"), + (0x1771, "X"), + (0x1772, "V"), + (0x1774, "X"), + (0x1780, "V"), + (0x17B4, "X"), + (0x17B6, "V"), + (0x17DE, "X"), + (0x17E0, "V"), + (0x17EA, "X"), + (0x17F0, "V"), + (0x17FA, "X"), + (0x1800, "V"), + (0x1806, "X"), + (0x1807, "V"), + (0x180B, "I"), + (0x180E, "X"), + (0x180F, "I"), + (0x1810, "V"), + (0x181A, "X"), + (0x1820, "V"), + (0x1879, "X"), + (0x1880, "V"), + (0x18AB, "X"), + (0x18B0, "V"), + (0x18F6, "X"), + (0x1900, "V"), + (0x191F, "X"), + (0x1920, "V"), + (0x192C, "X"), + (0x1930, "V"), + (0x193C, "X"), + (0x1940, "V"), + (0x1941, "X"), + (0x1944, "V"), + (0x196E, "X"), + (0x1970, "V"), + (0x1975, "X"), + (0x1980, "V"), + (0x19AC, "X"), + (0x19B0, "V"), + (0x19CA, "X"), + (0x19D0, "V"), + (0x19DB, "X"), + (0x19DE, "V"), + (0x1A1C, "X"), + (0x1A1E, "V"), + (0x1A5F, "X"), + (0x1A60, "V"), + (0x1A7D, "X"), + (0x1A7F, "V"), + (0x1A8A, "X"), + (0x1A90, "V"), + (0x1A9A, "X"), + (0x1AA0, "V"), + (0x1AAE, "X"), + (0x1AB0, "V"), + (0x1ACF, "X"), + (0x1B00, "V"), + (0x1B4D, "X"), + (0x1B50, "V"), + (0x1B7F, "X"), + (0x1B80, "V"), + (0x1BF4, "X"), + (0x1BFC, "V"), + (0x1C38, "X"), + (0x1C3B, "V"), + (0x1C4A, "X"), + (0x1C4D, "V"), + (0x1C80, "M", "в"), + ] + + +def _seg_15() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1C81, "M", "д"), + (0x1C82, "M", "о"), + (0x1C83, "M", "с"), + (0x1C84, "M", "т"), + (0x1C86, "M", "ъ"), + (0x1C87, "M", "ѣ"), + (0x1C88, "M", "ꙋ"), + (0x1C89, "X"), + (0x1C90, "M", "ა"), + (0x1C91, "M", "ბ"), + (0x1C92, "M", "გ"), + (0x1C93, "M", "დ"), + (0x1C94, "M", "ე"), + (0x1C95, "M", "ვ"), + (0x1C96, "M", "ზ"), + (0x1C97, "M", "თ"), + (0x1C98, "M", "ი"), + (0x1C99, "M", "კ"), + (0x1C9A, "M", "ლ"), + (0x1C9B, "M", "მ"), + (0x1C9C, "M", "ნ"), + (0x1C9D, "M", "ო"), + (0x1C9E, "M", "პ"), + (0x1C9F, "M", "ჟ"), + (0x1CA0, "M", "რ"), + (0x1CA1, "M", "ს"), + (0x1CA2, "M", "ტ"), + (0x1CA3, "M", "უ"), + (0x1CA4, "M", "ფ"), + (0x1CA5, "M", "ქ"), + (0x1CA6, "M", "ღ"), + (0x1CA7, "M", "ყ"), + (0x1CA8, "M", "შ"), + (0x1CA9, "M", "ჩ"), + (0x1CAA, "M", "ც"), + (0x1CAB, "M", "ძ"), + (0x1CAC, "M", "წ"), + (0x1CAD, "M", "ჭ"), + (0x1CAE, "M", "ხ"), + (0x1CAF, "M", "ჯ"), + (0x1CB0, "M", "ჰ"), + (0x1CB1, "M", "ჱ"), + (0x1CB2, "M", "ჲ"), + (0x1CB3, "M", "ჳ"), + (0x1CB4, "M", "ჴ"), + (0x1CB5, "M", "ჵ"), + (0x1CB6, "M", "ჶ"), + (0x1CB7, "M", "ჷ"), + (0x1CB8, "M", "ჸ"), + (0x1CB9, "M", "ჹ"), + (0x1CBA, "M", "ჺ"), + (0x1CBB, "X"), + (0x1CBD, "M", "ჽ"), + (0x1CBE, "M", "ჾ"), + (0x1CBF, "M", "ჿ"), + (0x1CC0, "V"), + (0x1CC8, "X"), + (0x1CD0, "V"), + (0x1CFB, "X"), + (0x1D00, "V"), + (0x1D2C, "M", "a"), + (0x1D2D, "M", "æ"), + (0x1D2E, "M", "b"), + (0x1D2F, "V"), + (0x1D30, "M", "d"), + (0x1D31, "M", "e"), + (0x1D32, "M", "ǝ"), + (0x1D33, "M", "g"), + (0x1D34, "M", "h"), + (0x1D35, "M", "i"), + (0x1D36, "M", "j"), + (0x1D37, "M", "k"), + (0x1D38, "M", "l"), + (0x1D39, "M", "m"), + (0x1D3A, "M", "n"), + (0x1D3B, "V"), + (0x1D3C, "M", "o"), + (0x1D3D, "M", "ȣ"), + (0x1D3E, "M", "p"), + (0x1D3F, "M", "r"), + (0x1D40, "M", "t"), + (0x1D41, "M", "u"), + (0x1D42, "M", "w"), + (0x1D43, "M", "a"), + (0x1D44, "M", "ɐ"), + (0x1D45, "M", "ɑ"), + (0x1D46, "M", "ᴂ"), + (0x1D47, "M", "b"), + (0x1D48, "M", "d"), + (0x1D49, "M", "e"), + (0x1D4A, "M", "ə"), + (0x1D4B, "M", "ɛ"), + (0x1D4C, "M", "ɜ"), + (0x1D4D, "M", "g"), + (0x1D4E, "V"), + (0x1D4F, "M", "k"), + (0x1D50, "M", "m"), + (0x1D51, "M", "ŋ"), + (0x1D52, "M", "o"), + (0x1D53, "M", "ɔ"), + ] + + +def _seg_16() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D54, "M", "ᴖ"), + (0x1D55, "M", "ᴗ"), + (0x1D56, "M", "p"), + (0x1D57, "M", "t"), + (0x1D58, "M", "u"), + (0x1D59, "M", "ᴝ"), + (0x1D5A, "M", "ɯ"), + (0x1D5B, "M", "v"), + (0x1D5C, "M", "ᴥ"), + (0x1D5D, "M", "β"), + (0x1D5E, "M", "γ"), + (0x1D5F, "M", "δ"), + (0x1D60, "M", "φ"), + (0x1D61, "M", "χ"), + (0x1D62, "M", "i"), + (0x1D63, "M", "r"), + (0x1D64, "M", "u"), + (0x1D65, "M", "v"), + (0x1D66, "M", "β"), + (0x1D67, "M", "γ"), + (0x1D68, "M", "ρ"), + (0x1D69, "M", "φ"), + (0x1D6A, "M", "χ"), + (0x1D6B, "V"), + (0x1D78, "M", "н"), + (0x1D79, "V"), + (0x1D9B, "M", "ɒ"), + (0x1D9C, "M", "c"), + (0x1D9D, "M", "ɕ"), + (0x1D9E, "M", "ð"), + (0x1D9F, "M", "ɜ"), + (0x1DA0, "M", "f"), + (0x1DA1, "M", "ɟ"), + (0x1DA2, "M", "ɡ"), + (0x1DA3, "M", "ɥ"), + (0x1DA4, "M", "ɨ"), + (0x1DA5, "M", "ɩ"), + (0x1DA6, "M", "ɪ"), + (0x1DA7, "M", "ᵻ"), + (0x1DA8, "M", "ʝ"), + (0x1DA9, "M", "ɭ"), + (0x1DAA, "M", "ᶅ"), + (0x1DAB, "M", "ʟ"), + (0x1DAC, "M", "ɱ"), + (0x1DAD, "M", "ɰ"), + (0x1DAE, "M", "ɲ"), + (0x1DAF, "M", "ɳ"), + (0x1DB0, "M", "ɴ"), + (0x1DB1, "M", "ɵ"), + (0x1DB2, "M", "ɸ"), + (0x1DB3, "M", "ʂ"), + (0x1DB4, "M", "ʃ"), + (0x1DB5, "M", "ƫ"), + (0x1DB6, "M", "ʉ"), + (0x1DB7, "M", "ʊ"), + (0x1DB8, "M", "ᴜ"), + (0x1DB9, "M", "ʋ"), + (0x1DBA, "M", "ʌ"), + (0x1DBB, "M", "z"), + (0x1DBC, "M", "ʐ"), + (0x1DBD, "M", "ʑ"), + (0x1DBE, "M", "ʒ"), + (0x1DBF, "M", "θ"), + (0x1DC0, "V"), + (0x1E00, "M", "ḁ"), + (0x1E01, "V"), + (0x1E02, "M", "ḃ"), + (0x1E03, "V"), + (0x1E04, "M", "ḅ"), + (0x1E05, "V"), + (0x1E06, "M", "ḇ"), + (0x1E07, "V"), + (0x1E08, "M", "ḉ"), + (0x1E09, "V"), + (0x1E0A, "M", "ḋ"), + (0x1E0B, "V"), + (0x1E0C, "M", "ḍ"), + (0x1E0D, "V"), + (0x1E0E, "M", "ḏ"), + (0x1E0F, "V"), + (0x1E10, "M", "ḑ"), + (0x1E11, "V"), + (0x1E12, "M", "ḓ"), + (0x1E13, "V"), + (0x1E14, "M", "ḕ"), + (0x1E15, "V"), + (0x1E16, "M", "ḗ"), + (0x1E17, "V"), + (0x1E18, "M", "ḙ"), + (0x1E19, "V"), + (0x1E1A, "M", "ḛ"), + (0x1E1B, "V"), + (0x1E1C, "M", "ḝ"), + (0x1E1D, "V"), + (0x1E1E, "M", "ḟ"), + (0x1E1F, "V"), + (0x1E20, "M", "ḡ"), + (0x1E21, "V"), + (0x1E22, "M", "ḣ"), + (0x1E23, "V"), + ] + + +def _seg_17() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E24, "M", "ḥ"), + (0x1E25, "V"), + (0x1E26, "M", "ḧ"), + (0x1E27, "V"), + (0x1E28, "M", "ḩ"), + (0x1E29, "V"), + (0x1E2A, "M", "ḫ"), + (0x1E2B, "V"), + (0x1E2C, "M", "ḭ"), + (0x1E2D, "V"), + (0x1E2E, "M", "ḯ"), + (0x1E2F, "V"), + (0x1E30, "M", "ḱ"), + (0x1E31, "V"), + (0x1E32, "M", "ḳ"), + (0x1E33, "V"), + (0x1E34, "M", "ḵ"), + (0x1E35, "V"), + (0x1E36, "M", "ḷ"), + (0x1E37, "V"), + (0x1E38, "M", "ḹ"), + (0x1E39, "V"), + (0x1E3A, "M", "ḻ"), + (0x1E3B, "V"), + (0x1E3C, "M", "ḽ"), + (0x1E3D, "V"), + (0x1E3E, "M", "ḿ"), + (0x1E3F, "V"), + (0x1E40, "M", "ṁ"), + (0x1E41, "V"), + (0x1E42, "M", "ṃ"), + (0x1E43, "V"), + (0x1E44, "M", "ṅ"), + (0x1E45, "V"), + (0x1E46, "M", "ṇ"), + (0x1E47, "V"), + (0x1E48, "M", "ṉ"), + (0x1E49, "V"), + (0x1E4A, "M", "ṋ"), + (0x1E4B, "V"), + (0x1E4C, "M", "ṍ"), + (0x1E4D, "V"), + (0x1E4E, "M", "ṏ"), + (0x1E4F, "V"), + (0x1E50, "M", "ṑ"), + (0x1E51, "V"), + (0x1E52, "M", "ṓ"), + (0x1E53, "V"), + (0x1E54, "M", "ṕ"), + (0x1E55, "V"), + (0x1E56, "M", "ṗ"), + (0x1E57, "V"), + (0x1E58, "M", "ṙ"), + (0x1E59, "V"), + (0x1E5A, "M", "ṛ"), + (0x1E5B, "V"), + (0x1E5C, "M", "ṝ"), + (0x1E5D, "V"), + (0x1E5E, "M", "ṟ"), + (0x1E5F, "V"), + (0x1E60, "M", "ṡ"), + (0x1E61, "V"), + (0x1E62, "M", "ṣ"), + (0x1E63, "V"), + (0x1E64, "M", "ṥ"), + (0x1E65, "V"), + (0x1E66, "M", "ṧ"), + (0x1E67, "V"), + (0x1E68, "M", "ṩ"), + (0x1E69, "V"), + (0x1E6A, "M", "ṫ"), + (0x1E6B, "V"), + (0x1E6C, "M", "ṭ"), + (0x1E6D, "V"), + (0x1E6E, "M", "ṯ"), + (0x1E6F, "V"), + (0x1E70, "M", "ṱ"), + (0x1E71, "V"), + (0x1E72, "M", "ṳ"), + (0x1E73, "V"), + (0x1E74, "M", "ṵ"), + (0x1E75, "V"), + (0x1E76, "M", "ṷ"), + (0x1E77, "V"), + (0x1E78, "M", "ṹ"), + (0x1E79, "V"), + (0x1E7A, "M", "ṻ"), + (0x1E7B, "V"), + (0x1E7C, "M", "ṽ"), + (0x1E7D, "V"), + (0x1E7E, "M", "ṿ"), + (0x1E7F, "V"), + (0x1E80, "M", "ẁ"), + (0x1E81, "V"), + (0x1E82, "M", "ẃ"), + (0x1E83, "V"), + (0x1E84, "M", "ẅ"), + (0x1E85, "V"), + (0x1E86, "M", "ẇ"), + (0x1E87, "V"), + ] + + +def _seg_18() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E88, "M", "ẉ"), + (0x1E89, "V"), + (0x1E8A, "M", "ẋ"), + (0x1E8B, "V"), + (0x1E8C, "M", "ẍ"), + (0x1E8D, "V"), + (0x1E8E, "M", "ẏ"), + (0x1E8F, "V"), + (0x1E90, "M", "ẑ"), + (0x1E91, "V"), + (0x1E92, "M", "ẓ"), + (0x1E93, "V"), + (0x1E94, "M", "ẕ"), + (0x1E95, "V"), + (0x1E9A, "M", "aʾ"), + (0x1E9B, "M", "ṡ"), + (0x1E9C, "V"), + (0x1E9E, "M", "ß"), + (0x1E9F, "V"), + (0x1EA0, "M", "ạ"), + (0x1EA1, "V"), + (0x1EA2, "M", "ả"), + (0x1EA3, "V"), + (0x1EA4, "M", "ấ"), + (0x1EA5, "V"), + (0x1EA6, "M", "ầ"), + (0x1EA7, "V"), + (0x1EA8, "M", "ẩ"), + (0x1EA9, "V"), + (0x1EAA, "M", "ẫ"), + (0x1EAB, "V"), + (0x1EAC, "M", "ậ"), + (0x1EAD, "V"), + (0x1EAE, "M", "ắ"), + (0x1EAF, "V"), + (0x1EB0, "M", "ằ"), + (0x1EB1, "V"), + (0x1EB2, "M", "ẳ"), + (0x1EB3, "V"), + (0x1EB4, "M", "ẵ"), + (0x1EB5, "V"), + (0x1EB6, "M", "ặ"), + (0x1EB7, "V"), + (0x1EB8, "M", "ẹ"), + (0x1EB9, "V"), + (0x1EBA, "M", "ẻ"), + (0x1EBB, "V"), + (0x1EBC, "M", "ẽ"), + (0x1EBD, "V"), + (0x1EBE, "M", "ế"), + (0x1EBF, "V"), + (0x1EC0, "M", "ề"), + (0x1EC1, "V"), + (0x1EC2, "M", "ể"), + (0x1EC3, "V"), + (0x1EC4, "M", "ễ"), + (0x1EC5, "V"), + (0x1EC6, "M", "ệ"), + (0x1EC7, "V"), + (0x1EC8, "M", "ỉ"), + (0x1EC9, "V"), + (0x1ECA, "M", "ị"), + (0x1ECB, "V"), + (0x1ECC, "M", "ọ"), + (0x1ECD, "V"), + (0x1ECE, "M", "ỏ"), + (0x1ECF, "V"), + (0x1ED0, "M", "ố"), + (0x1ED1, "V"), + (0x1ED2, "M", "ồ"), + (0x1ED3, "V"), + (0x1ED4, "M", "ổ"), + (0x1ED5, "V"), + (0x1ED6, "M", "ỗ"), + (0x1ED7, "V"), + (0x1ED8, "M", "ộ"), + (0x1ED9, "V"), + (0x1EDA, "M", "ớ"), + (0x1EDB, "V"), + (0x1EDC, "M", "ờ"), + (0x1EDD, "V"), + (0x1EDE, "M", "ở"), + (0x1EDF, "V"), + (0x1EE0, "M", "ỡ"), + (0x1EE1, "V"), + (0x1EE2, "M", "ợ"), + (0x1EE3, "V"), + (0x1EE4, "M", "ụ"), + (0x1EE5, "V"), + (0x1EE6, "M", "ủ"), + (0x1EE7, "V"), + (0x1EE8, "M", "ứ"), + (0x1EE9, "V"), + (0x1EEA, "M", "ừ"), + (0x1EEB, "V"), + (0x1EEC, "M", "ử"), + (0x1EED, "V"), + (0x1EEE, "M", "ữ"), + (0x1EEF, "V"), + (0x1EF0, "M", "ự"), + ] + + +def _seg_19() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EF1, "V"), + (0x1EF2, "M", "ỳ"), + (0x1EF3, "V"), + (0x1EF4, "M", "ỵ"), + (0x1EF5, "V"), + (0x1EF6, "M", "ỷ"), + (0x1EF7, "V"), + (0x1EF8, "M", "ỹ"), + (0x1EF9, "V"), + (0x1EFA, "M", "ỻ"), + (0x1EFB, "V"), + (0x1EFC, "M", "ỽ"), + (0x1EFD, "V"), + (0x1EFE, "M", "ỿ"), + (0x1EFF, "V"), + (0x1F08, "M", "ἀ"), + (0x1F09, "M", "ἁ"), + (0x1F0A, "M", "ἂ"), + (0x1F0B, "M", "ἃ"), + (0x1F0C, "M", "ἄ"), + (0x1F0D, "M", "ἅ"), + (0x1F0E, "M", "ἆ"), + (0x1F0F, "M", "ἇ"), + (0x1F10, "V"), + (0x1F16, "X"), + (0x1F18, "M", "ἐ"), + (0x1F19, "M", "ἑ"), + (0x1F1A, "M", "ἒ"), + (0x1F1B, "M", "ἓ"), + (0x1F1C, "M", "ἔ"), + (0x1F1D, "M", "ἕ"), + (0x1F1E, "X"), + (0x1F20, "V"), + (0x1F28, "M", "ἠ"), + (0x1F29, "M", "ἡ"), + (0x1F2A, "M", "ἢ"), + (0x1F2B, "M", "ἣ"), + (0x1F2C, "M", "ἤ"), + (0x1F2D, "M", "ἥ"), + (0x1F2E, "M", "ἦ"), + (0x1F2F, "M", "ἧ"), + (0x1F30, "V"), + (0x1F38, "M", "ἰ"), + (0x1F39, "M", "ἱ"), + (0x1F3A, "M", "ἲ"), + (0x1F3B, "M", "ἳ"), + (0x1F3C, "M", "ἴ"), + (0x1F3D, "M", "ἵ"), + (0x1F3E, "M", "ἶ"), + (0x1F3F, "M", "ἷ"), + (0x1F40, "V"), + (0x1F46, "X"), + (0x1F48, "M", "ὀ"), + (0x1F49, "M", "ὁ"), + (0x1F4A, "M", "ὂ"), + (0x1F4B, "M", "ὃ"), + (0x1F4C, "M", "ὄ"), + (0x1F4D, "M", "ὅ"), + (0x1F4E, "X"), + (0x1F50, "V"), + (0x1F58, "X"), + (0x1F59, "M", "ὑ"), + (0x1F5A, "X"), + (0x1F5B, "M", "ὓ"), + (0x1F5C, "X"), + (0x1F5D, "M", "ὕ"), + (0x1F5E, "X"), + (0x1F5F, "M", "ὗ"), + (0x1F60, "V"), + (0x1F68, "M", "ὠ"), + (0x1F69, "M", "ὡ"), + (0x1F6A, "M", "ὢ"), + (0x1F6B, "M", "ὣ"), + (0x1F6C, "M", "ὤ"), + (0x1F6D, "M", "ὥ"), + (0x1F6E, "M", "ὦ"), + (0x1F6F, "M", "ὧ"), + (0x1F70, "V"), + (0x1F71, "M", "ά"), + (0x1F72, "V"), + (0x1F73, "M", "έ"), + (0x1F74, "V"), + (0x1F75, "M", "ή"), + (0x1F76, "V"), + (0x1F77, "M", "ί"), + (0x1F78, "V"), + (0x1F79, "M", "ό"), + (0x1F7A, "V"), + (0x1F7B, "M", "ύ"), + (0x1F7C, "V"), + (0x1F7D, "M", "ώ"), + (0x1F7E, "X"), + (0x1F80, "M", "ἀι"), + (0x1F81, "M", "ἁι"), + (0x1F82, "M", "ἂι"), + (0x1F83, "M", "ἃι"), + (0x1F84, "M", "ἄι"), + (0x1F85, "M", "ἅι"), + (0x1F86, "M", "ἆι"), + (0x1F87, "M", "ἇι"), + ] + + +def _seg_20() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1F88, "M", "ἀι"), + (0x1F89, "M", "ἁι"), + (0x1F8A, "M", "ἂι"), + (0x1F8B, "M", "ἃι"), + (0x1F8C, "M", "ἄι"), + (0x1F8D, "M", "ἅι"), + (0x1F8E, "M", "ἆι"), + (0x1F8F, "M", "ἇι"), + (0x1F90, "M", "ἠι"), + (0x1F91, "M", "ἡι"), + (0x1F92, "M", "ἢι"), + (0x1F93, "M", "ἣι"), + (0x1F94, "M", "ἤι"), + (0x1F95, "M", "ἥι"), + (0x1F96, "M", "ἦι"), + (0x1F97, "M", "ἧι"), + (0x1F98, "M", "ἠι"), + (0x1F99, "M", "ἡι"), + (0x1F9A, "M", "ἢι"), + (0x1F9B, "M", "ἣι"), + (0x1F9C, "M", "ἤι"), + (0x1F9D, "M", "ἥι"), + (0x1F9E, "M", "ἦι"), + (0x1F9F, "M", "ἧι"), + (0x1FA0, "M", "ὠι"), + (0x1FA1, "M", "ὡι"), + (0x1FA2, "M", "ὢι"), + (0x1FA3, "M", "ὣι"), + (0x1FA4, "M", "ὤι"), + (0x1FA5, "M", "ὥι"), + (0x1FA6, "M", "ὦι"), + (0x1FA7, "M", "ὧι"), + (0x1FA8, "M", "ὠι"), + (0x1FA9, "M", "ὡι"), + (0x1FAA, "M", "ὢι"), + (0x1FAB, "M", "ὣι"), + (0x1FAC, "M", "ὤι"), + (0x1FAD, "M", "ὥι"), + (0x1FAE, "M", "ὦι"), + (0x1FAF, "M", "ὧι"), + (0x1FB0, "V"), + (0x1FB2, "M", "ὰι"), + (0x1FB3, "M", "αι"), + (0x1FB4, "M", "άι"), + (0x1FB5, "X"), + (0x1FB6, "V"), + (0x1FB7, "M", "ᾶι"), + (0x1FB8, "M", "ᾰ"), + (0x1FB9, "M", "ᾱ"), + (0x1FBA, "M", "ὰ"), + (0x1FBB, "M", "ά"), + (0x1FBC, "M", "αι"), + (0x1FBD, "3", " ̓"), + (0x1FBE, "M", "ι"), + (0x1FBF, "3", " ̓"), + (0x1FC0, "3", " ͂"), + (0x1FC1, "3", " ̈͂"), + (0x1FC2, "M", "ὴι"), + (0x1FC3, "M", "ηι"), + (0x1FC4, "M", "ήι"), + (0x1FC5, "X"), + (0x1FC6, "V"), + (0x1FC7, "M", "ῆι"), + (0x1FC8, "M", "ὲ"), + (0x1FC9, "M", "έ"), + (0x1FCA, "M", "ὴ"), + (0x1FCB, "M", "ή"), + (0x1FCC, "M", "ηι"), + (0x1FCD, "3", " ̓̀"), + (0x1FCE, "3", " ̓́"), + (0x1FCF, "3", " ̓͂"), + (0x1FD0, "V"), + (0x1FD3, "M", "ΐ"), + (0x1FD4, "X"), + (0x1FD6, "V"), + (0x1FD8, "M", "ῐ"), + (0x1FD9, "M", "ῑ"), + (0x1FDA, "M", "ὶ"), + (0x1FDB, "M", "ί"), + (0x1FDC, "X"), + (0x1FDD, "3", " ̔̀"), + (0x1FDE, "3", " ̔́"), + (0x1FDF, "3", " ̔͂"), + (0x1FE0, "V"), + (0x1FE3, "M", "ΰ"), + (0x1FE4, "V"), + (0x1FE8, "M", "ῠ"), + (0x1FE9, "M", "ῡ"), + (0x1FEA, "M", "ὺ"), + (0x1FEB, "M", "ύ"), + (0x1FEC, "M", "ῥ"), + (0x1FED, "3", " ̈̀"), + (0x1FEE, "3", " ̈́"), + (0x1FEF, "3", "`"), + (0x1FF0, "X"), + (0x1FF2, "M", "ὼι"), + (0x1FF3, "M", "ωι"), + (0x1FF4, "M", "ώι"), + (0x1FF5, "X"), + (0x1FF6, "V"), + ] + + +def _seg_21() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1FF7, "M", "ῶι"), + (0x1FF8, "M", "ὸ"), + (0x1FF9, "M", "ό"), + (0x1FFA, "M", "ὼ"), + (0x1FFB, "M", "ώ"), + (0x1FFC, "M", "ωι"), + (0x1FFD, "3", " ́"), + (0x1FFE, "3", " ̔"), + (0x1FFF, "X"), + (0x2000, "3", " "), + (0x200B, "I"), + (0x200C, "D", ""), + (0x200E, "X"), + (0x2010, "V"), + (0x2011, "M", "‐"), + (0x2012, "V"), + (0x2017, "3", " ̳"), + (0x2018, "V"), + (0x2024, "X"), + (0x2027, "V"), + (0x2028, "X"), + (0x202F, "3", " "), + (0x2030, "V"), + (0x2033, "M", "′′"), + (0x2034, "M", "′′′"), + (0x2035, "V"), + (0x2036, "M", "‵‵"), + (0x2037, "M", "‵‵‵"), + (0x2038, "V"), + (0x203C, "3", "!!"), + (0x203D, "V"), + (0x203E, "3", " ̅"), + (0x203F, "V"), + (0x2047, "3", "??"), + (0x2048, "3", "?!"), + (0x2049, "3", "!?"), + (0x204A, "V"), + (0x2057, "M", "′′′′"), + (0x2058, "V"), + (0x205F, "3", " "), + (0x2060, "I"), + (0x2061, "X"), + (0x2064, "I"), + (0x2065, "X"), + (0x2070, "M", "0"), + (0x2071, "M", "i"), + (0x2072, "X"), + (0x2074, "M", "4"), + (0x2075, "M", "5"), + (0x2076, "M", "6"), + (0x2077, "M", "7"), + (0x2078, "M", "8"), + (0x2079, "M", "9"), + (0x207A, "3", "+"), + (0x207B, "M", "−"), + (0x207C, "3", "="), + (0x207D, "3", "("), + (0x207E, "3", ")"), + (0x207F, "M", "n"), + (0x2080, "M", "0"), + (0x2081, "M", "1"), + (0x2082, "M", "2"), + (0x2083, "M", "3"), + (0x2084, "M", "4"), + (0x2085, "M", "5"), + (0x2086, "M", "6"), + (0x2087, "M", "7"), + (0x2088, "M", "8"), + (0x2089, "M", "9"), + (0x208A, "3", "+"), + (0x208B, "M", "−"), + (0x208C, "3", "="), + (0x208D, "3", "("), + (0x208E, "3", ")"), + (0x208F, "X"), + (0x2090, "M", "a"), + (0x2091, "M", "e"), + (0x2092, "M", "o"), + (0x2093, "M", "x"), + (0x2094, "M", "ə"), + (0x2095, "M", "h"), + (0x2096, "M", "k"), + (0x2097, "M", "l"), + (0x2098, "M", "m"), + (0x2099, "M", "n"), + (0x209A, "M", "p"), + (0x209B, "M", "s"), + (0x209C, "M", "t"), + (0x209D, "X"), + (0x20A0, "V"), + (0x20A8, "M", "rs"), + (0x20A9, "V"), + (0x20C1, "X"), + (0x20D0, "V"), + (0x20F1, "X"), + (0x2100, "3", "a/c"), + (0x2101, "3", "a/s"), + (0x2102, "M", "c"), + (0x2103, "M", "°c"), + (0x2104, "V"), + ] + + +def _seg_22() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2105, "3", "c/o"), + (0x2106, "3", "c/u"), + (0x2107, "M", "ɛ"), + (0x2108, "V"), + (0x2109, "M", "°f"), + (0x210A, "M", "g"), + (0x210B, "M", "h"), + (0x210F, "M", "ħ"), + (0x2110, "M", "i"), + (0x2112, "M", "l"), + (0x2114, "V"), + (0x2115, "M", "n"), + (0x2116, "M", "no"), + (0x2117, "V"), + (0x2119, "M", "p"), + (0x211A, "M", "q"), + (0x211B, "M", "r"), + (0x211E, "V"), + (0x2120, "M", "sm"), + (0x2121, "M", "tel"), + (0x2122, "M", "tm"), + (0x2123, "V"), + (0x2124, "M", "z"), + (0x2125, "V"), + (0x2126, "M", "ω"), + (0x2127, "V"), + (0x2128, "M", "z"), + (0x2129, "V"), + (0x212A, "M", "k"), + (0x212B, "M", "å"), + (0x212C, "M", "b"), + (0x212D, "M", "c"), + (0x212E, "V"), + (0x212F, "M", "e"), + (0x2131, "M", "f"), + (0x2132, "X"), + (0x2133, "M", "m"), + (0x2134, "M", "o"), + (0x2135, "M", "א"), + (0x2136, "M", "ב"), + (0x2137, "M", "ג"), + (0x2138, "M", "ד"), + (0x2139, "M", "i"), + (0x213A, "V"), + (0x213B, "M", "fax"), + (0x213C, "M", "π"), + (0x213D, "M", "γ"), + (0x213F, "M", "π"), + (0x2140, "M", "∑"), + (0x2141, "V"), + (0x2145, "M", "d"), + (0x2147, "M", "e"), + (0x2148, "M", "i"), + (0x2149, "M", "j"), + (0x214A, "V"), + (0x2150, "M", "1⁄7"), + (0x2151, "M", "1⁄9"), + (0x2152, "M", "1⁄10"), + (0x2153, "M", "1⁄3"), + (0x2154, "M", "2⁄3"), + (0x2155, "M", "1⁄5"), + (0x2156, "M", "2⁄5"), + (0x2157, "M", "3⁄5"), + (0x2158, "M", "4⁄5"), + (0x2159, "M", "1⁄6"), + (0x215A, "M", "5⁄6"), + (0x215B, "M", "1⁄8"), + (0x215C, "M", "3⁄8"), + (0x215D, "M", "5⁄8"), + (0x215E, "M", "7⁄8"), + (0x215F, "M", "1⁄"), + (0x2160, "M", "i"), + (0x2161, "M", "ii"), + (0x2162, "M", "iii"), + (0x2163, "M", "iv"), + (0x2164, "M", "v"), + (0x2165, "M", "vi"), + (0x2166, "M", "vii"), + (0x2167, "M", "viii"), + (0x2168, "M", "ix"), + (0x2169, "M", "x"), + (0x216A, "M", "xi"), + (0x216B, "M", "xii"), + (0x216C, "M", "l"), + (0x216D, "M", "c"), + (0x216E, "M", "d"), + (0x216F, "M", "m"), + (0x2170, "M", "i"), + (0x2171, "M", "ii"), + (0x2172, "M", "iii"), + (0x2173, "M", "iv"), + (0x2174, "M", "v"), + (0x2175, "M", "vi"), + (0x2176, "M", "vii"), + (0x2177, "M", "viii"), + (0x2178, "M", "ix"), + (0x2179, "M", "x"), + (0x217A, "M", "xi"), + (0x217B, "M", "xii"), + (0x217C, "M", "l"), + ] + + +def _seg_23() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x217D, "M", "c"), + (0x217E, "M", "d"), + (0x217F, "M", "m"), + (0x2180, "V"), + (0x2183, "X"), + (0x2184, "V"), + (0x2189, "M", "0⁄3"), + (0x218A, "V"), + (0x218C, "X"), + (0x2190, "V"), + (0x222C, "M", "∫∫"), + (0x222D, "M", "∫∫∫"), + (0x222E, "V"), + (0x222F, "M", "∮∮"), + (0x2230, "M", "∮∮∮"), + (0x2231, "V"), + (0x2329, "M", "〈"), + (0x232A, "M", "〉"), + (0x232B, "V"), + (0x2427, "X"), + (0x2440, "V"), + (0x244B, "X"), + (0x2460, "M", "1"), + (0x2461, "M", "2"), + (0x2462, "M", "3"), + (0x2463, "M", "4"), + (0x2464, "M", "5"), + (0x2465, "M", "6"), + (0x2466, "M", "7"), + (0x2467, "M", "8"), + (0x2468, "M", "9"), + (0x2469, "M", "10"), + (0x246A, "M", "11"), + (0x246B, "M", "12"), + (0x246C, "M", "13"), + (0x246D, "M", "14"), + (0x246E, "M", "15"), + (0x246F, "M", "16"), + (0x2470, "M", "17"), + (0x2471, "M", "18"), + (0x2472, "M", "19"), + (0x2473, "M", "20"), + (0x2474, "3", "(1)"), + (0x2475, "3", "(2)"), + (0x2476, "3", "(3)"), + (0x2477, "3", "(4)"), + (0x2478, "3", "(5)"), + (0x2479, "3", "(6)"), + (0x247A, "3", "(7)"), + (0x247B, "3", "(8)"), + (0x247C, "3", "(9)"), + (0x247D, "3", "(10)"), + (0x247E, "3", "(11)"), + (0x247F, "3", "(12)"), + (0x2480, "3", "(13)"), + (0x2481, "3", "(14)"), + (0x2482, "3", "(15)"), + (0x2483, "3", "(16)"), + (0x2484, "3", "(17)"), + (0x2485, "3", "(18)"), + (0x2486, "3", "(19)"), + (0x2487, "3", "(20)"), + (0x2488, "X"), + (0x249C, "3", "(a)"), + (0x249D, "3", "(b)"), + (0x249E, "3", "(c)"), + (0x249F, "3", "(d)"), + (0x24A0, "3", "(e)"), + (0x24A1, "3", "(f)"), + (0x24A2, "3", "(g)"), + (0x24A3, "3", "(h)"), + (0x24A4, "3", "(i)"), + (0x24A5, "3", "(j)"), + (0x24A6, "3", "(k)"), + (0x24A7, "3", "(l)"), + (0x24A8, "3", "(m)"), + (0x24A9, "3", "(n)"), + (0x24AA, "3", "(o)"), + (0x24AB, "3", "(p)"), + (0x24AC, "3", "(q)"), + (0x24AD, "3", "(r)"), + (0x24AE, "3", "(s)"), + (0x24AF, "3", "(t)"), + (0x24B0, "3", "(u)"), + (0x24B1, "3", "(v)"), + (0x24B2, "3", "(w)"), + (0x24B3, "3", "(x)"), + (0x24B4, "3", "(y)"), + (0x24B5, "3", "(z)"), + (0x24B6, "M", "a"), + (0x24B7, "M", "b"), + (0x24B8, "M", "c"), + (0x24B9, "M", "d"), + (0x24BA, "M", "e"), + (0x24BB, "M", "f"), + (0x24BC, "M", "g"), + (0x24BD, "M", "h"), + (0x24BE, "M", "i"), + (0x24BF, "M", "j"), + (0x24C0, "M", "k"), + ] + + +def _seg_24() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x24C1, "M", "l"), + (0x24C2, "M", "m"), + (0x24C3, "M", "n"), + (0x24C4, "M", "o"), + (0x24C5, "M", "p"), + (0x24C6, "M", "q"), + (0x24C7, "M", "r"), + (0x24C8, "M", "s"), + (0x24C9, "M", "t"), + (0x24CA, "M", "u"), + (0x24CB, "M", "v"), + (0x24CC, "M", "w"), + (0x24CD, "M", "x"), + (0x24CE, "M", "y"), + (0x24CF, "M", "z"), + (0x24D0, "M", "a"), + (0x24D1, "M", "b"), + (0x24D2, "M", "c"), + (0x24D3, "M", "d"), + (0x24D4, "M", "e"), + (0x24D5, "M", "f"), + (0x24D6, "M", "g"), + (0x24D7, "M", "h"), + (0x24D8, "M", "i"), + (0x24D9, "M", "j"), + (0x24DA, "M", "k"), + (0x24DB, "M", "l"), + (0x24DC, "M", "m"), + (0x24DD, "M", "n"), + (0x24DE, "M", "o"), + (0x24DF, "M", "p"), + (0x24E0, "M", "q"), + (0x24E1, "M", "r"), + (0x24E2, "M", "s"), + (0x24E3, "M", "t"), + (0x24E4, "M", "u"), + (0x24E5, "M", "v"), + (0x24E6, "M", "w"), + (0x24E7, "M", "x"), + (0x24E8, "M", "y"), + (0x24E9, "M", "z"), + (0x24EA, "M", "0"), + (0x24EB, "V"), + (0x2A0C, "M", "∫∫∫∫"), + (0x2A0D, "V"), + (0x2A74, "3", "::="), + (0x2A75, "3", "=="), + (0x2A76, "3", "==="), + (0x2A77, "V"), + (0x2ADC, "M", "⫝̸"), + (0x2ADD, "V"), + (0x2B74, "X"), + (0x2B76, "V"), + (0x2B96, "X"), + (0x2B97, "V"), + (0x2C00, "M", "ⰰ"), + (0x2C01, "M", "ⰱ"), + (0x2C02, "M", "ⰲ"), + (0x2C03, "M", "ⰳ"), + (0x2C04, "M", "ⰴ"), + (0x2C05, "M", "ⰵ"), + (0x2C06, "M", "ⰶ"), + (0x2C07, "M", "ⰷ"), + (0x2C08, "M", "ⰸ"), + (0x2C09, "M", "ⰹ"), + (0x2C0A, "M", "ⰺ"), + (0x2C0B, "M", "ⰻ"), + (0x2C0C, "M", "ⰼ"), + (0x2C0D, "M", "ⰽ"), + (0x2C0E, "M", "ⰾ"), + (0x2C0F, "M", "ⰿ"), + (0x2C10, "M", "ⱀ"), + (0x2C11, "M", "ⱁ"), + (0x2C12, "M", "ⱂ"), + (0x2C13, "M", "ⱃ"), + (0x2C14, "M", "ⱄ"), + (0x2C15, "M", "ⱅ"), + (0x2C16, "M", "ⱆ"), + (0x2C17, "M", "ⱇ"), + (0x2C18, "M", "ⱈ"), + (0x2C19, "M", "ⱉ"), + (0x2C1A, "M", "ⱊ"), + (0x2C1B, "M", "ⱋ"), + (0x2C1C, "M", "ⱌ"), + (0x2C1D, "M", "ⱍ"), + (0x2C1E, "M", "ⱎ"), + (0x2C1F, "M", "ⱏ"), + (0x2C20, "M", "ⱐ"), + (0x2C21, "M", "ⱑ"), + (0x2C22, "M", "ⱒ"), + (0x2C23, "M", "ⱓ"), + (0x2C24, "M", "ⱔ"), + (0x2C25, "M", "ⱕ"), + (0x2C26, "M", "ⱖ"), + (0x2C27, "M", "ⱗ"), + (0x2C28, "M", "ⱘ"), + (0x2C29, "M", "ⱙ"), + (0x2C2A, "M", "ⱚ"), + (0x2C2B, "M", "ⱛ"), + (0x2C2C, "M", "ⱜ"), + ] + + +def _seg_25() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2C2D, "M", "ⱝ"), + (0x2C2E, "M", "ⱞ"), + (0x2C2F, "M", "ⱟ"), + (0x2C30, "V"), + (0x2C60, "M", "ⱡ"), + (0x2C61, "V"), + (0x2C62, "M", "ɫ"), + (0x2C63, "M", "ᵽ"), + (0x2C64, "M", "ɽ"), + (0x2C65, "V"), + (0x2C67, "M", "ⱨ"), + (0x2C68, "V"), + (0x2C69, "M", "ⱪ"), + (0x2C6A, "V"), + (0x2C6B, "M", "ⱬ"), + (0x2C6C, "V"), + (0x2C6D, "M", "ɑ"), + (0x2C6E, "M", "ɱ"), + (0x2C6F, "M", "ɐ"), + (0x2C70, "M", "ɒ"), + (0x2C71, "V"), + (0x2C72, "M", "ⱳ"), + (0x2C73, "V"), + (0x2C75, "M", "ⱶ"), + (0x2C76, "V"), + (0x2C7C, "M", "j"), + (0x2C7D, "M", "v"), + (0x2C7E, "M", "ȿ"), + (0x2C7F, "M", "ɀ"), + (0x2C80, "M", "ⲁ"), + (0x2C81, "V"), + (0x2C82, "M", "ⲃ"), + (0x2C83, "V"), + (0x2C84, "M", "ⲅ"), + (0x2C85, "V"), + (0x2C86, "M", "ⲇ"), + (0x2C87, "V"), + (0x2C88, "M", "ⲉ"), + (0x2C89, "V"), + (0x2C8A, "M", "ⲋ"), + (0x2C8B, "V"), + (0x2C8C, "M", "ⲍ"), + (0x2C8D, "V"), + (0x2C8E, "M", "ⲏ"), + (0x2C8F, "V"), + (0x2C90, "M", "ⲑ"), + (0x2C91, "V"), + (0x2C92, "M", "ⲓ"), + (0x2C93, "V"), + (0x2C94, "M", "ⲕ"), + (0x2C95, "V"), + (0x2C96, "M", "ⲗ"), + (0x2C97, "V"), + (0x2C98, "M", "ⲙ"), + (0x2C99, "V"), + (0x2C9A, "M", "ⲛ"), + (0x2C9B, "V"), + (0x2C9C, "M", "ⲝ"), + (0x2C9D, "V"), + (0x2C9E, "M", "ⲟ"), + (0x2C9F, "V"), + (0x2CA0, "M", "ⲡ"), + (0x2CA1, "V"), + (0x2CA2, "M", "ⲣ"), + (0x2CA3, "V"), + (0x2CA4, "M", "ⲥ"), + (0x2CA5, "V"), + (0x2CA6, "M", "ⲧ"), + (0x2CA7, "V"), + (0x2CA8, "M", "ⲩ"), + (0x2CA9, "V"), + (0x2CAA, "M", "ⲫ"), + (0x2CAB, "V"), + (0x2CAC, "M", "ⲭ"), + (0x2CAD, "V"), + (0x2CAE, "M", "ⲯ"), + (0x2CAF, "V"), + (0x2CB0, "M", "ⲱ"), + (0x2CB1, "V"), + (0x2CB2, "M", "ⲳ"), + (0x2CB3, "V"), + (0x2CB4, "M", "ⲵ"), + (0x2CB5, "V"), + (0x2CB6, "M", "ⲷ"), + (0x2CB7, "V"), + (0x2CB8, "M", "ⲹ"), + (0x2CB9, "V"), + (0x2CBA, "M", "ⲻ"), + (0x2CBB, "V"), + (0x2CBC, "M", "ⲽ"), + (0x2CBD, "V"), + (0x2CBE, "M", "ⲿ"), + (0x2CBF, "V"), + (0x2CC0, "M", "ⳁ"), + (0x2CC1, "V"), + (0x2CC2, "M", "ⳃ"), + (0x2CC3, "V"), + (0x2CC4, "M", "ⳅ"), + (0x2CC5, "V"), + (0x2CC6, "M", "ⳇ"), + ] + + +def _seg_26() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2CC7, "V"), + (0x2CC8, "M", "ⳉ"), + (0x2CC9, "V"), + (0x2CCA, "M", "ⳋ"), + (0x2CCB, "V"), + (0x2CCC, "M", "ⳍ"), + (0x2CCD, "V"), + (0x2CCE, "M", "ⳏ"), + (0x2CCF, "V"), + (0x2CD0, "M", "ⳑ"), + (0x2CD1, "V"), + (0x2CD2, "M", "ⳓ"), + (0x2CD3, "V"), + (0x2CD4, "M", "ⳕ"), + (0x2CD5, "V"), + (0x2CD6, "M", "ⳗ"), + (0x2CD7, "V"), + (0x2CD8, "M", "ⳙ"), + (0x2CD9, "V"), + (0x2CDA, "M", "ⳛ"), + (0x2CDB, "V"), + (0x2CDC, "M", "ⳝ"), + (0x2CDD, "V"), + (0x2CDE, "M", "ⳟ"), + (0x2CDF, "V"), + (0x2CE0, "M", "ⳡ"), + (0x2CE1, "V"), + (0x2CE2, "M", "ⳣ"), + (0x2CE3, "V"), + (0x2CEB, "M", "ⳬ"), + (0x2CEC, "V"), + (0x2CED, "M", "ⳮ"), + (0x2CEE, "V"), + (0x2CF2, "M", "ⳳ"), + (0x2CF3, "V"), + (0x2CF4, "X"), + (0x2CF9, "V"), + (0x2D26, "X"), + (0x2D27, "V"), + (0x2D28, "X"), + (0x2D2D, "V"), + (0x2D2E, "X"), + (0x2D30, "V"), + (0x2D68, "X"), + (0x2D6F, "M", "ⵡ"), + (0x2D70, "V"), + (0x2D71, "X"), + (0x2D7F, "V"), + (0x2D97, "X"), + (0x2DA0, "V"), + (0x2DA7, "X"), + (0x2DA8, "V"), + (0x2DAF, "X"), + (0x2DB0, "V"), + (0x2DB7, "X"), + (0x2DB8, "V"), + (0x2DBF, "X"), + (0x2DC0, "V"), + (0x2DC7, "X"), + (0x2DC8, "V"), + (0x2DCF, "X"), + (0x2DD0, "V"), + (0x2DD7, "X"), + (0x2DD8, "V"), + (0x2DDF, "X"), + (0x2DE0, "V"), + (0x2E5E, "X"), + (0x2E80, "V"), + (0x2E9A, "X"), + (0x2E9B, "V"), + (0x2E9F, "M", "母"), + (0x2EA0, "V"), + (0x2EF3, "M", "龟"), + (0x2EF4, "X"), + (0x2F00, "M", "一"), + (0x2F01, "M", "丨"), + (0x2F02, "M", "丶"), + (0x2F03, "M", "丿"), + (0x2F04, "M", "乙"), + (0x2F05, "M", "亅"), + (0x2F06, "M", "二"), + (0x2F07, "M", "亠"), + (0x2F08, "M", "人"), + (0x2F09, "M", "儿"), + (0x2F0A, "M", "入"), + (0x2F0B, "M", "八"), + (0x2F0C, "M", "冂"), + (0x2F0D, "M", "冖"), + (0x2F0E, "M", "冫"), + (0x2F0F, "M", "几"), + (0x2F10, "M", "凵"), + (0x2F11, "M", "刀"), + (0x2F12, "M", "力"), + (0x2F13, "M", "勹"), + (0x2F14, "M", "匕"), + (0x2F15, "M", "匚"), + (0x2F16, "M", "匸"), + (0x2F17, "M", "十"), + (0x2F18, "M", "卜"), + (0x2F19, "M", "卩"), + ] + + +def _seg_27() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F1A, "M", "厂"), + (0x2F1B, "M", "厶"), + (0x2F1C, "M", "又"), + (0x2F1D, "M", "口"), + (0x2F1E, "M", "囗"), + (0x2F1F, "M", "土"), + (0x2F20, "M", "士"), + (0x2F21, "M", "夂"), + (0x2F22, "M", "夊"), + (0x2F23, "M", "夕"), + (0x2F24, "M", "大"), + (0x2F25, "M", "女"), + (0x2F26, "M", "子"), + (0x2F27, "M", "宀"), + (0x2F28, "M", "寸"), + (0x2F29, "M", "小"), + (0x2F2A, "M", "尢"), + (0x2F2B, "M", "尸"), + (0x2F2C, "M", "屮"), + (0x2F2D, "M", "山"), + (0x2F2E, "M", "巛"), + (0x2F2F, "M", "工"), + (0x2F30, "M", "己"), + (0x2F31, "M", "巾"), + (0x2F32, "M", "干"), + (0x2F33, "M", "幺"), + (0x2F34, "M", "广"), + (0x2F35, "M", "廴"), + (0x2F36, "M", "廾"), + (0x2F37, "M", "弋"), + (0x2F38, "M", "弓"), + (0x2F39, "M", "彐"), + (0x2F3A, "M", "彡"), + (0x2F3B, "M", "彳"), + (0x2F3C, "M", "心"), + (0x2F3D, "M", "戈"), + (0x2F3E, "M", "戶"), + (0x2F3F, "M", "手"), + (0x2F40, "M", "支"), + (0x2F41, "M", "攴"), + (0x2F42, "M", "文"), + (0x2F43, "M", "斗"), + (0x2F44, "M", "斤"), + (0x2F45, "M", "方"), + (0x2F46, "M", "无"), + (0x2F47, "M", "日"), + (0x2F48, "M", "曰"), + (0x2F49, "M", "月"), + (0x2F4A, "M", "木"), + (0x2F4B, "M", "欠"), + (0x2F4C, "M", "止"), + (0x2F4D, "M", "歹"), + (0x2F4E, "M", "殳"), + (0x2F4F, "M", "毋"), + (0x2F50, "M", "比"), + (0x2F51, "M", "毛"), + (0x2F52, "M", "氏"), + (0x2F53, "M", "气"), + (0x2F54, "M", "水"), + (0x2F55, "M", "火"), + (0x2F56, "M", "爪"), + (0x2F57, "M", "父"), + (0x2F58, "M", "爻"), + (0x2F59, "M", "爿"), + (0x2F5A, "M", "片"), + (0x2F5B, "M", "牙"), + (0x2F5C, "M", "牛"), + (0x2F5D, "M", "犬"), + (0x2F5E, "M", "玄"), + (0x2F5F, "M", "玉"), + (0x2F60, "M", "瓜"), + (0x2F61, "M", "瓦"), + (0x2F62, "M", "甘"), + (0x2F63, "M", "生"), + (0x2F64, "M", "用"), + (0x2F65, "M", "田"), + (0x2F66, "M", "疋"), + (0x2F67, "M", "疒"), + (0x2F68, "M", "癶"), + (0x2F69, "M", "白"), + (0x2F6A, "M", "皮"), + (0x2F6B, "M", "皿"), + (0x2F6C, "M", "目"), + (0x2F6D, "M", "矛"), + (0x2F6E, "M", "矢"), + (0x2F6F, "M", "石"), + (0x2F70, "M", "示"), + (0x2F71, "M", "禸"), + (0x2F72, "M", "禾"), + (0x2F73, "M", "穴"), + (0x2F74, "M", "立"), + (0x2F75, "M", "竹"), + (0x2F76, "M", "米"), + (0x2F77, "M", "糸"), + (0x2F78, "M", "缶"), + (0x2F79, "M", "网"), + (0x2F7A, "M", "羊"), + (0x2F7B, "M", "羽"), + (0x2F7C, "M", "老"), + (0x2F7D, "M", "而"), + ] + + +def _seg_28() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F7E, "M", "耒"), + (0x2F7F, "M", "耳"), + (0x2F80, "M", "聿"), + (0x2F81, "M", "肉"), + (0x2F82, "M", "臣"), + (0x2F83, "M", "自"), + (0x2F84, "M", "至"), + (0x2F85, "M", "臼"), + (0x2F86, "M", "舌"), + (0x2F87, "M", "舛"), + (0x2F88, "M", "舟"), + (0x2F89, "M", "艮"), + (0x2F8A, "M", "色"), + (0x2F8B, "M", "艸"), + (0x2F8C, "M", "虍"), + (0x2F8D, "M", "虫"), + (0x2F8E, "M", "血"), + (0x2F8F, "M", "行"), + (0x2F90, "M", "衣"), + (0x2F91, "M", "襾"), + (0x2F92, "M", "見"), + (0x2F93, "M", "角"), + (0x2F94, "M", "言"), + (0x2F95, "M", "谷"), + (0x2F96, "M", "豆"), + (0x2F97, "M", "豕"), + (0x2F98, "M", "豸"), + (0x2F99, "M", "貝"), + (0x2F9A, "M", "赤"), + (0x2F9B, "M", "走"), + (0x2F9C, "M", "足"), + (0x2F9D, "M", "身"), + (0x2F9E, "M", "車"), + (0x2F9F, "M", "辛"), + (0x2FA0, "M", "辰"), + (0x2FA1, "M", "辵"), + (0x2FA2, "M", "邑"), + (0x2FA3, "M", "酉"), + (0x2FA4, "M", "釆"), + (0x2FA5, "M", "里"), + (0x2FA6, "M", "金"), + (0x2FA7, "M", "長"), + (0x2FA8, "M", "門"), + (0x2FA9, "M", "阜"), + (0x2FAA, "M", "隶"), + (0x2FAB, "M", "隹"), + (0x2FAC, "M", "雨"), + (0x2FAD, "M", "靑"), + (0x2FAE, "M", "非"), + (0x2FAF, "M", "面"), + (0x2FB0, "M", "革"), + (0x2FB1, "M", "韋"), + (0x2FB2, "M", "韭"), + (0x2FB3, "M", "音"), + (0x2FB4, "M", "頁"), + (0x2FB5, "M", "風"), + (0x2FB6, "M", "飛"), + (0x2FB7, "M", "食"), + (0x2FB8, "M", "首"), + (0x2FB9, "M", "香"), + (0x2FBA, "M", "馬"), + (0x2FBB, "M", "骨"), + (0x2FBC, "M", "高"), + (0x2FBD, "M", "髟"), + (0x2FBE, "M", "鬥"), + (0x2FBF, "M", "鬯"), + (0x2FC0, "M", "鬲"), + (0x2FC1, "M", "鬼"), + (0x2FC2, "M", "魚"), + (0x2FC3, "M", "鳥"), + (0x2FC4, "M", "鹵"), + (0x2FC5, "M", "鹿"), + (0x2FC6, "M", "麥"), + (0x2FC7, "M", "麻"), + (0x2FC8, "M", "黃"), + (0x2FC9, "M", "黍"), + (0x2FCA, "M", "黑"), + (0x2FCB, "M", "黹"), + (0x2FCC, "M", "黽"), + (0x2FCD, "M", "鼎"), + (0x2FCE, "M", "鼓"), + (0x2FCF, "M", "鼠"), + (0x2FD0, "M", "鼻"), + (0x2FD1, "M", "齊"), + (0x2FD2, "M", "齒"), + (0x2FD3, "M", "龍"), + (0x2FD4, "M", "龜"), + (0x2FD5, "M", "龠"), + (0x2FD6, "X"), + (0x3000, "3", " "), + (0x3001, "V"), + (0x3002, "M", "."), + (0x3003, "V"), + (0x3036, "M", "〒"), + (0x3037, "V"), + (0x3038, "M", "十"), + (0x3039, "M", "卄"), + (0x303A, "M", "卅"), + (0x303B, "V"), + (0x3040, "X"), + ] + + +def _seg_29() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3041, "V"), + (0x3097, "X"), + (0x3099, "V"), + (0x309B, "3", " ゙"), + (0x309C, "3", " ゚"), + (0x309D, "V"), + (0x309F, "M", "より"), + (0x30A0, "V"), + (0x30FF, "M", "コト"), + (0x3100, "X"), + (0x3105, "V"), + (0x3130, "X"), + (0x3131, "M", "ᄀ"), + (0x3132, "M", "ᄁ"), + (0x3133, "M", "ᆪ"), + (0x3134, "M", "ᄂ"), + (0x3135, "M", "ᆬ"), + (0x3136, "M", "ᆭ"), + (0x3137, "M", "ᄃ"), + (0x3138, "M", "ᄄ"), + (0x3139, "M", "ᄅ"), + (0x313A, "M", "ᆰ"), + (0x313B, "M", "ᆱ"), + (0x313C, "M", "ᆲ"), + (0x313D, "M", "ᆳ"), + (0x313E, "M", "ᆴ"), + (0x313F, "M", "ᆵ"), + (0x3140, "M", "ᄚ"), + (0x3141, "M", "ᄆ"), + (0x3142, "M", "ᄇ"), + (0x3143, "M", "ᄈ"), + (0x3144, "M", "ᄡ"), + (0x3145, "M", "ᄉ"), + (0x3146, "M", "ᄊ"), + (0x3147, "M", "ᄋ"), + (0x3148, "M", "ᄌ"), + (0x3149, "M", "ᄍ"), + (0x314A, "M", "ᄎ"), + (0x314B, "M", "ᄏ"), + (0x314C, "M", "ᄐ"), + (0x314D, "M", "ᄑ"), + (0x314E, "M", "ᄒ"), + (0x314F, "M", "ᅡ"), + (0x3150, "M", "ᅢ"), + (0x3151, "M", "ᅣ"), + (0x3152, "M", "ᅤ"), + (0x3153, "M", "ᅥ"), + (0x3154, "M", "ᅦ"), + (0x3155, "M", "ᅧ"), + (0x3156, "M", "ᅨ"), + (0x3157, "M", "ᅩ"), + (0x3158, "M", "ᅪ"), + (0x3159, "M", "ᅫ"), + (0x315A, "M", "ᅬ"), + (0x315B, "M", "ᅭ"), + (0x315C, "M", "ᅮ"), + (0x315D, "M", "ᅯ"), + (0x315E, "M", "ᅰ"), + (0x315F, "M", "ᅱ"), + (0x3160, "M", "ᅲ"), + (0x3161, "M", "ᅳ"), + (0x3162, "M", "ᅴ"), + (0x3163, "M", "ᅵ"), + (0x3164, "X"), + (0x3165, "M", "ᄔ"), + (0x3166, "M", "ᄕ"), + (0x3167, "M", "ᇇ"), + (0x3168, "M", "ᇈ"), + (0x3169, "M", "ᇌ"), + (0x316A, "M", "ᇎ"), + (0x316B, "M", "ᇓ"), + (0x316C, "M", "ᇗ"), + (0x316D, "M", "ᇙ"), + (0x316E, "M", "ᄜ"), + (0x316F, "M", "ᇝ"), + (0x3170, "M", "ᇟ"), + (0x3171, "M", "ᄝ"), + (0x3172, "M", "ᄞ"), + (0x3173, "M", "ᄠ"), + (0x3174, "M", "ᄢ"), + (0x3175, "M", "ᄣ"), + (0x3176, "M", "ᄧ"), + (0x3177, "M", "ᄩ"), + (0x3178, "M", "ᄫ"), + (0x3179, "M", "ᄬ"), + (0x317A, "M", "ᄭ"), + (0x317B, "M", "ᄮ"), + (0x317C, "M", "ᄯ"), + (0x317D, "M", "ᄲ"), + (0x317E, "M", "ᄶ"), + (0x317F, "M", "ᅀ"), + (0x3180, "M", "ᅇ"), + (0x3181, "M", "ᅌ"), + (0x3182, "M", "ᇱ"), + (0x3183, "M", "ᇲ"), + (0x3184, "M", "ᅗ"), + (0x3185, "M", "ᅘ"), + (0x3186, "M", "ᅙ"), + (0x3187, "M", "ᆄ"), + (0x3188, "M", "ᆅ"), + ] + + +def _seg_30() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3189, "M", "ᆈ"), + (0x318A, "M", "ᆑ"), + (0x318B, "M", "ᆒ"), + (0x318C, "M", "ᆔ"), + (0x318D, "M", "ᆞ"), + (0x318E, "M", "ᆡ"), + (0x318F, "X"), + (0x3190, "V"), + (0x3192, "M", "一"), + (0x3193, "M", "二"), + (0x3194, "M", "三"), + (0x3195, "M", "四"), + (0x3196, "M", "上"), + (0x3197, "M", "中"), + (0x3198, "M", "下"), + (0x3199, "M", "甲"), + (0x319A, "M", "乙"), + (0x319B, "M", "丙"), + (0x319C, "M", "丁"), + (0x319D, "M", "天"), + (0x319E, "M", "地"), + (0x319F, "M", "人"), + (0x31A0, "V"), + (0x31E4, "X"), + (0x31F0, "V"), + (0x3200, "3", "(ᄀ)"), + (0x3201, "3", "(ᄂ)"), + (0x3202, "3", "(ᄃ)"), + (0x3203, "3", "(ᄅ)"), + (0x3204, "3", "(ᄆ)"), + (0x3205, "3", "(ᄇ)"), + (0x3206, "3", "(ᄉ)"), + (0x3207, "3", "(ᄋ)"), + (0x3208, "3", "(ᄌ)"), + (0x3209, "3", "(ᄎ)"), + (0x320A, "3", "(ᄏ)"), + (0x320B, "3", "(ᄐ)"), + (0x320C, "3", "(ᄑ)"), + (0x320D, "3", "(ᄒ)"), + (0x320E, "3", "(가)"), + (0x320F, "3", "(나)"), + (0x3210, "3", "(다)"), + (0x3211, "3", "(라)"), + (0x3212, "3", "(마)"), + (0x3213, "3", "(바)"), + (0x3214, "3", "(사)"), + (0x3215, "3", "(아)"), + (0x3216, "3", "(자)"), + (0x3217, "3", "(차)"), + (0x3218, "3", "(카)"), + (0x3219, "3", "(타)"), + (0x321A, "3", "(파)"), + (0x321B, "3", "(하)"), + (0x321C, "3", "(주)"), + (0x321D, "3", "(오전)"), + (0x321E, "3", "(오후)"), + (0x321F, "X"), + (0x3220, "3", "(一)"), + (0x3221, "3", "(二)"), + (0x3222, "3", "(三)"), + (0x3223, "3", "(四)"), + (0x3224, "3", "(五)"), + (0x3225, "3", "(六)"), + (0x3226, "3", "(七)"), + (0x3227, "3", "(八)"), + (0x3228, "3", "(九)"), + (0x3229, "3", "(十)"), + (0x322A, "3", "(月)"), + (0x322B, "3", "(火)"), + (0x322C, "3", "(水)"), + (0x322D, "3", "(木)"), + (0x322E, "3", "(金)"), + (0x322F, "3", "(土)"), + (0x3230, "3", "(日)"), + (0x3231, "3", "(株)"), + (0x3232, "3", "(有)"), + (0x3233, "3", "(社)"), + (0x3234, "3", "(名)"), + (0x3235, "3", "(特)"), + (0x3236, "3", "(財)"), + (0x3237, "3", "(祝)"), + (0x3238, "3", "(労)"), + (0x3239, "3", "(代)"), + (0x323A, "3", "(呼)"), + (0x323B, "3", "(学)"), + (0x323C, "3", "(監)"), + (0x323D, "3", "(企)"), + (0x323E, "3", "(資)"), + (0x323F, "3", "(協)"), + (0x3240, "3", "(祭)"), + (0x3241, "3", "(休)"), + (0x3242, "3", "(自)"), + (0x3243, "3", "(至)"), + (0x3244, "M", "問"), + (0x3245, "M", "幼"), + (0x3246, "M", "文"), + (0x3247, "M", "箏"), + (0x3248, "V"), + (0x3250, "M", "pte"), + (0x3251, "M", "21"), + ] + + +def _seg_31() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x3252, "M", "22"), + (0x3253, "M", "23"), + (0x3254, "M", "24"), + (0x3255, "M", "25"), + (0x3256, "M", "26"), + (0x3257, "M", "27"), + (0x3258, "M", "28"), + (0x3259, "M", "29"), + (0x325A, "M", "30"), + (0x325B, "M", "31"), + (0x325C, "M", "32"), + (0x325D, "M", "33"), + (0x325E, "M", "34"), + (0x325F, "M", "35"), + (0x3260, "M", "ᄀ"), + (0x3261, "M", "ᄂ"), + (0x3262, "M", "ᄃ"), + (0x3263, "M", "ᄅ"), + (0x3264, "M", "ᄆ"), + (0x3265, "M", "ᄇ"), + (0x3266, "M", "ᄉ"), + (0x3267, "M", "ᄋ"), + (0x3268, "M", "ᄌ"), + (0x3269, "M", "ᄎ"), + (0x326A, "M", "ᄏ"), + (0x326B, "M", "ᄐ"), + (0x326C, "M", "ᄑ"), + (0x326D, "M", "ᄒ"), + (0x326E, "M", "가"), + (0x326F, "M", "나"), + (0x3270, "M", "다"), + (0x3271, "M", "라"), + (0x3272, "M", "마"), + (0x3273, "M", "바"), + (0x3274, "M", "사"), + (0x3275, "M", "아"), + (0x3276, "M", "자"), + (0x3277, "M", "차"), + (0x3278, "M", "카"), + (0x3279, "M", "타"), + (0x327A, "M", "파"), + (0x327B, "M", "하"), + (0x327C, "M", "참고"), + (0x327D, "M", "주의"), + (0x327E, "M", "우"), + (0x327F, "V"), + (0x3280, "M", "一"), + (0x3281, "M", "二"), + (0x3282, "M", "三"), + (0x3283, "M", "四"), + (0x3284, "M", "五"), + (0x3285, "M", "六"), + (0x3286, "M", "七"), + (0x3287, "M", "八"), + (0x3288, "M", "九"), + (0x3289, "M", "十"), + (0x328A, "M", "月"), + (0x328B, "M", "火"), + (0x328C, "M", "水"), + (0x328D, "M", "木"), + (0x328E, "M", "金"), + (0x328F, "M", "土"), + (0x3290, "M", "日"), + (0x3291, "M", "株"), + (0x3292, "M", "有"), + (0x3293, "M", "社"), + (0x3294, "M", "名"), + (0x3295, "M", "特"), + (0x3296, "M", "財"), + (0x3297, "M", "祝"), + (0x3298, "M", "労"), + (0x3299, "M", "秘"), + (0x329A, "M", "男"), + (0x329B, "M", "女"), + (0x329C, "M", "適"), + (0x329D, "M", "優"), + (0x329E, "M", "印"), + (0x329F, "M", "注"), + (0x32A0, "M", "項"), + (0x32A1, "M", "休"), + (0x32A2, "M", "写"), + (0x32A3, "M", "正"), + (0x32A4, "M", "上"), + (0x32A5, "M", "中"), + (0x32A6, "M", "下"), + (0x32A7, "M", "左"), + (0x32A8, "M", "右"), + (0x32A9, "M", "医"), + (0x32AA, "M", "宗"), + (0x32AB, "M", "学"), + (0x32AC, "M", "監"), + (0x32AD, "M", "企"), + (0x32AE, "M", "資"), + (0x32AF, "M", "協"), + (0x32B0, "M", "夜"), + (0x32B1, "M", "36"), + (0x32B2, "M", "37"), + (0x32B3, "M", "38"), + (0x32B4, "M", "39"), + (0x32B5, "M", "40"), + ] + + +def _seg_32() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x32B6, "M", "41"), + (0x32B7, "M", "42"), + (0x32B8, "M", "43"), + (0x32B9, "M", "44"), + (0x32BA, "M", "45"), + (0x32BB, "M", "46"), + (0x32BC, "M", "47"), + (0x32BD, "M", "48"), + (0x32BE, "M", "49"), + (0x32BF, "M", "50"), + (0x32C0, "M", "1月"), + (0x32C1, "M", "2月"), + (0x32C2, "M", "3月"), + (0x32C3, "M", "4月"), + (0x32C4, "M", "5月"), + (0x32C5, "M", "6月"), + (0x32C6, "M", "7月"), + (0x32C7, "M", "8月"), + (0x32C8, "M", "9月"), + (0x32C9, "M", "10月"), + (0x32CA, "M", "11月"), + (0x32CB, "M", "12月"), + (0x32CC, "M", "hg"), + (0x32CD, "M", "erg"), + (0x32CE, "M", "ev"), + (0x32CF, "M", "ltd"), + (0x32D0, "M", "ア"), + (0x32D1, "M", "イ"), + (0x32D2, "M", "ウ"), + (0x32D3, "M", "エ"), + (0x32D4, "M", "オ"), + (0x32D5, "M", "カ"), + (0x32D6, "M", "キ"), + (0x32D7, "M", "ク"), + (0x32D8, "M", "ケ"), + (0x32D9, "M", "コ"), + (0x32DA, "M", "サ"), + (0x32DB, "M", "シ"), + (0x32DC, "M", "ス"), + (0x32DD, "M", "セ"), + (0x32DE, "M", "ソ"), + (0x32DF, "M", "タ"), + (0x32E0, "M", "チ"), + (0x32E1, "M", "ツ"), + (0x32E2, "M", "テ"), + (0x32E3, "M", "ト"), + (0x32E4, "M", "ナ"), + (0x32E5, "M", "ニ"), + (0x32E6, "M", "ヌ"), + (0x32E7, "M", "ネ"), + (0x32E8, "M", "ノ"), + (0x32E9, "M", "ハ"), + (0x32EA, "M", "ヒ"), + (0x32EB, "M", "フ"), + (0x32EC, "M", "ヘ"), + (0x32ED, "M", "ホ"), + (0x32EE, "M", "マ"), + (0x32EF, "M", "ミ"), + (0x32F0, "M", "ム"), + (0x32F1, "M", "メ"), + (0x32F2, "M", "モ"), + (0x32F3, "M", "ヤ"), + (0x32F4, "M", "ユ"), + (0x32F5, "M", "ヨ"), + (0x32F6, "M", "ラ"), + (0x32F7, "M", "リ"), + (0x32F8, "M", "ル"), + (0x32F9, "M", "レ"), + (0x32FA, "M", "ロ"), + (0x32FB, "M", "ワ"), + (0x32FC, "M", "ヰ"), + (0x32FD, "M", "ヱ"), + (0x32FE, "M", "ヲ"), + (0x32FF, "M", "令和"), + (0x3300, "M", "アパート"), + (0x3301, "M", "アルファ"), + (0x3302, "M", "アンペア"), + (0x3303, "M", "アール"), + (0x3304, "M", "イニング"), + (0x3305, "M", "インチ"), + (0x3306, "M", "ウォン"), + (0x3307, "M", "エスクード"), + (0x3308, "M", "エーカー"), + (0x3309, "M", "オンス"), + (0x330A, "M", "オーム"), + (0x330B, "M", "カイリ"), + (0x330C, "M", "カラット"), + (0x330D, "M", "カロリー"), + (0x330E, "M", "ガロン"), + (0x330F, "M", "ガンマ"), + (0x3310, "M", "ギガ"), + (0x3311, "M", "ギニー"), + (0x3312, "M", "キュリー"), + (0x3313, "M", "ギルダー"), + (0x3314, "M", "キロ"), + (0x3315, "M", "キログラム"), + (0x3316, "M", "キロメートル"), + (0x3317, "M", "キロワット"), + (0x3318, "M", "グラム"), + (0x3319, "M", "グラムトン"), + ] + + +def _seg_33() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x331A, "M", "クルゼイロ"), + (0x331B, "M", "クローネ"), + (0x331C, "M", "ケース"), + (0x331D, "M", "コルナ"), + (0x331E, "M", "コーポ"), + (0x331F, "M", "サイクル"), + (0x3320, "M", "サンチーム"), + (0x3321, "M", "シリング"), + (0x3322, "M", "センチ"), + (0x3323, "M", "セント"), + (0x3324, "M", "ダース"), + (0x3325, "M", "デシ"), + (0x3326, "M", "ドル"), + (0x3327, "M", "トン"), + (0x3328, "M", "ナノ"), + (0x3329, "M", "ノット"), + (0x332A, "M", "ハイツ"), + (0x332B, "M", "パーセント"), + (0x332C, "M", "パーツ"), + (0x332D, "M", "バーレル"), + (0x332E, "M", "ピアストル"), + (0x332F, "M", "ピクル"), + (0x3330, "M", "ピコ"), + (0x3331, "M", "ビル"), + (0x3332, "M", "ファラッド"), + (0x3333, "M", "フィート"), + (0x3334, "M", "ブッシェル"), + (0x3335, "M", "フラン"), + (0x3336, "M", "ヘクタール"), + (0x3337, "M", "ペソ"), + (0x3338, "M", "ペニヒ"), + (0x3339, "M", "ヘルツ"), + (0x333A, "M", "ペンス"), + (0x333B, "M", "ページ"), + (0x333C, "M", "ベータ"), + (0x333D, "M", "ポイント"), + (0x333E, "M", "ボルト"), + (0x333F, "M", "ホン"), + (0x3340, "M", "ポンド"), + (0x3341, "M", "ホール"), + (0x3342, "M", "ホーン"), + (0x3343, "M", "マイクロ"), + (0x3344, "M", "マイル"), + (0x3345, "M", "マッハ"), + (0x3346, "M", "マルク"), + (0x3347, "M", "マンション"), + (0x3348, "M", "ミクロン"), + (0x3349, "M", "ミリ"), + (0x334A, "M", "ミリバール"), + (0x334B, "M", "メガ"), + (0x334C, "M", "メガトン"), + (0x334D, "M", "メートル"), + (0x334E, "M", "ヤード"), + (0x334F, "M", "ヤール"), + (0x3350, "M", "ユアン"), + (0x3351, "M", "リットル"), + (0x3352, "M", "リラ"), + (0x3353, "M", "ルピー"), + (0x3354, "M", "ルーブル"), + (0x3355, "M", "レム"), + (0x3356, "M", "レントゲン"), + (0x3357, "M", "ワット"), + (0x3358, "M", "0点"), + (0x3359, "M", "1点"), + (0x335A, "M", "2点"), + (0x335B, "M", "3点"), + (0x335C, "M", "4点"), + (0x335D, "M", "5点"), + (0x335E, "M", "6点"), + (0x335F, "M", "7点"), + (0x3360, "M", "8点"), + (0x3361, "M", "9点"), + (0x3362, "M", "10点"), + (0x3363, "M", "11点"), + (0x3364, "M", "12点"), + (0x3365, "M", "13点"), + (0x3366, "M", "14点"), + (0x3367, "M", "15点"), + (0x3368, "M", "16点"), + (0x3369, "M", "17点"), + (0x336A, "M", "18点"), + (0x336B, "M", "19点"), + (0x336C, "M", "20点"), + (0x336D, "M", "21点"), + (0x336E, "M", "22点"), + (0x336F, "M", "23点"), + (0x3370, "M", "24点"), + (0x3371, "M", "hpa"), + (0x3372, "M", "da"), + (0x3373, "M", "au"), + (0x3374, "M", "bar"), + (0x3375, "M", "ov"), + (0x3376, "M", "pc"), + (0x3377, "M", "dm"), + (0x3378, "M", "dm2"), + (0x3379, "M", "dm3"), + (0x337A, "M", "iu"), + (0x337B, "M", "平成"), + (0x337C, "M", "昭和"), + (0x337D, "M", "大正"), + ] + + +def _seg_34() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x337E, "M", "明治"), + (0x337F, "M", "株式会社"), + (0x3380, "M", "pa"), + (0x3381, "M", "na"), + (0x3382, "M", "μa"), + (0x3383, "M", "ma"), + (0x3384, "M", "ka"), + (0x3385, "M", "kb"), + (0x3386, "M", "mb"), + (0x3387, "M", "gb"), + (0x3388, "M", "cal"), + (0x3389, "M", "kcal"), + (0x338A, "M", "pf"), + (0x338B, "M", "nf"), + (0x338C, "M", "μf"), + (0x338D, "M", "μg"), + (0x338E, "M", "mg"), + (0x338F, "M", "kg"), + (0x3390, "M", "hz"), + (0x3391, "M", "khz"), + (0x3392, "M", "mhz"), + (0x3393, "M", "ghz"), + (0x3394, "M", "thz"), + (0x3395, "M", "μl"), + (0x3396, "M", "ml"), + (0x3397, "M", "dl"), + (0x3398, "M", "kl"), + (0x3399, "M", "fm"), + (0x339A, "M", "nm"), + (0x339B, "M", "μm"), + (0x339C, "M", "mm"), + (0x339D, "M", "cm"), + (0x339E, "M", "km"), + (0x339F, "M", "mm2"), + (0x33A0, "M", "cm2"), + (0x33A1, "M", "m2"), + (0x33A2, "M", "km2"), + (0x33A3, "M", "mm3"), + (0x33A4, "M", "cm3"), + (0x33A5, "M", "m3"), + (0x33A6, "M", "km3"), + (0x33A7, "M", "m∕s"), + (0x33A8, "M", "m∕s2"), + (0x33A9, "M", "pa"), + (0x33AA, "M", "kpa"), + (0x33AB, "M", "mpa"), + (0x33AC, "M", "gpa"), + (0x33AD, "M", "rad"), + (0x33AE, "M", "rad∕s"), + (0x33AF, "M", "rad∕s2"), + (0x33B0, "M", "ps"), + (0x33B1, "M", "ns"), + (0x33B2, "M", "μs"), + (0x33B3, "M", "ms"), + (0x33B4, "M", "pv"), + (0x33B5, "M", "nv"), + (0x33B6, "M", "μv"), + (0x33B7, "M", "mv"), + (0x33B8, "M", "kv"), + (0x33B9, "M", "mv"), + (0x33BA, "M", "pw"), + (0x33BB, "M", "nw"), + (0x33BC, "M", "μw"), + (0x33BD, "M", "mw"), + (0x33BE, "M", "kw"), + (0x33BF, "M", "mw"), + (0x33C0, "M", "kω"), + (0x33C1, "M", "mω"), + (0x33C2, "X"), + (0x33C3, "M", "bq"), + (0x33C4, "M", "cc"), + (0x33C5, "M", "cd"), + (0x33C6, "M", "c∕kg"), + (0x33C7, "X"), + (0x33C8, "M", "db"), + (0x33C9, "M", "gy"), + (0x33CA, "M", "ha"), + (0x33CB, "M", "hp"), + (0x33CC, "M", "in"), + (0x33CD, "M", "kk"), + (0x33CE, "M", "km"), + (0x33CF, "M", "kt"), + (0x33D0, "M", "lm"), + (0x33D1, "M", "ln"), + (0x33D2, "M", "log"), + (0x33D3, "M", "lx"), + (0x33D4, "M", "mb"), + (0x33D5, "M", "mil"), + (0x33D6, "M", "mol"), + (0x33D7, "M", "ph"), + (0x33D8, "X"), + (0x33D9, "M", "ppm"), + (0x33DA, "M", "pr"), + (0x33DB, "M", "sr"), + (0x33DC, "M", "sv"), + (0x33DD, "M", "wb"), + (0x33DE, "M", "v∕m"), + (0x33DF, "M", "a∕m"), + (0x33E0, "M", "1日"), + (0x33E1, "M", "2日"), + ] + + +def _seg_35() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x33E2, "M", "3日"), + (0x33E3, "M", "4日"), + (0x33E4, "M", "5日"), + (0x33E5, "M", "6日"), + (0x33E6, "M", "7日"), + (0x33E7, "M", "8日"), + (0x33E8, "M", "9日"), + (0x33E9, "M", "10日"), + (0x33EA, "M", "11日"), + (0x33EB, "M", "12日"), + (0x33EC, "M", "13日"), + (0x33ED, "M", "14日"), + (0x33EE, "M", "15日"), + (0x33EF, "M", "16日"), + (0x33F0, "M", "17日"), + (0x33F1, "M", "18日"), + (0x33F2, "M", "19日"), + (0x33F3, "M", "20日"), + (0x33F4, "M", "21日"), + (0x33F5, "M", "22日"), + (0x33F6, "M", "23日"), + (0x33F7, "M", "24日"), + (0x33F8, "M", "25日"), + (0x33F9, "M", "26日"), + (0x33FA, "M", "27日"), + (0x33FB, "M", "28日"), + (0x33FC, "M", "29日"), + (0x33FD, "M", "30日"), + (0x33FE, "M", "31日"), + (0x33FF, "M", "gal"), + (0x3400, "V"), + (0xA48D, "X"), + (0xA490, "V"), + (0xA4C7, "X"), + (0xA4D0, "V"), + (0xA62C, "X"), + (0xA640, "M", "ꙁ"), + (0xA641, "V"), + (0xA642, "M", "ꙃ"), + (0xA643, "V"), + (0xA644, "M", "ꙅ"), + (0xA645, "V"), + (0xA646, "M", "ꙇ"), + (0xA647, "V"), + (0xA648, "M", "ꙉ"), + (0xA649, "V"), + (0xA64A, "M", "ꙋ"), + (0xA64B, "V"), + (0xA64C, "M", "ꙍ"), + (0xA64D, "V"), + (0xA64E, "M", "ꙏ"), + (0xA64F, "V"), + (0xA650, "M", "ꙑ"), + (0xA651, "V"), + (0xA652, "M", "ꙓ"), + (0xA653, "V"), + (0xA654, "M", "ꙕ"), + (0xA655, "V"), + (0xA656, "M", "ꙗ"), + (0xA657, "V"), + (0xA658, "M", "ꙙ"), + (0xA659, "V"), + (0xA65A, "M", "ꙛ"), + (0xA65B, "V"), + (0xA65C, "M", "ꙝ"), + (0xA65D, "V"), + (0xA65E, "M", "ꙟ"), + (0xA65F, "V"), + (0xA660, "M", "ꙡ"), + (0xA661, "V"), + (0xA662, "M", "ꙣ"), + (0xA663, "V"), + (0xA664, "M", "ꙥ"), + (0xA665, "V"), + (0xA666, "M", "ꙧ"), + (0xA667, "V"), + (0xA668, "M", "ꙩ"), + (0xA669, "V"), + (0xA66A, "M", "ꙫ"), + (0xA66B, "V"), + (0xA66C, "M", "ꙭ"), + (0xA66D, "V"), + (0xA680, "M", "ꚁ"), + (0xA681, "V"), + (0xA682, "M", "ꚃ"), + (0xA683, "V"), + (0xA684, "M", "ꚅ"), + (0xA685, "V"), + (0xA686, "M", "ꚇ"), + (0xA687, "V"), + (0xA688, "M", "ꚉ"), + (0xA689, "V"), + (0xA68A, "M", "ꚋ"), + (0xA68B, "V"), + (0xA68C, "M", "ꚍ"), + (0xA68D, "V"), + (0xA68E, "M", "ꚏ"), + (0xA68F, "V"), + (0xA690, "M", "ꚑ"), + (0xA691, "V"), + ] + + +def _seg_36() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA692, "M", "ꚓ"), + (0xA693, "V"), + (0xA694, "M", "ꚕ"), + (0xA695, "V"), + (0xA696, "M", "ꚗ"), + (0xA697, "V"), + (0xA698, "M", "ꚙ"), + (0xA699, "V"), + (0xA69A, "M", "ꚛ"), + (0xA69B, "V"), + (0xA69C, "M", "ъ"), + (0xA69D, "M", "ь"), + (0xA69E, "V"), + (0xA6F8, "X"), + (0xA700, "V"), + (0xA722, "M", "ꜣ"), + (0xA723, "V"), + (0xA724, "M", "ꜥ"), + (0xA725, "V"), + (0xA726, "M", "ꜧ"), + (0xA727, "V"), + (0xA728, "M", "ꜩ"), + (0xA729, "V"), + (0xA72A, "M", "ꜫ"), + (0xA72B, "V"), + (0xA72C, "M", "ꜭ"), + (0xA72D, "V"), + (0xA72E, "M", "ꜯ"), + (0xA72F, "V"), + (0xA732, "M", "ꜳ"), + (0xA733, "V"), + (0xA734, "M", "ꜵ"), + (0xA735, "V"), + (0xA736, "M", "ꜷ"), + (0xA737, "V"), + (0xA738, "M", "ꜹ"), + (0xA739, "V"), + (0xA73A, "M", "ꜻ"), + (0xA73B, "V"), + (0xA73C, "M", "ꜽ"), + (0xA73D, "V"), + (0xA73E, "M", "ꜿ"), + (0xA73F, "V"), + (0xA740, "M", "ꝁ"), + (0xA741, "V"), + (0xA742, "M", "ꝃ"), + (0xA743, "V"), + (0xA744, "M", "ꝅ"), + (0xA745, "V"), + (0xA746, "M", "ꝇ"), + (0xA747, "V"), + (0xA748, "M", "ꝉ"), + (0xA749, "V"), + (0xA74A, "M", "ꝋ"), + (0xA74B, "V"), + (0xA74C, "M", "ꝍ"), + (0xA74D, "V"), + (0xA74E, "M", "ꝏ"), + (0xA74F, "V"), + (0xA750, "M", "ꝑ"), + (0xA751, "V"), + (0xA752, "M", "ꝓ"), + (0xA753, "V"), + (0xA754, "M", "ꝕ"), + (0xA755, "V"), + (0xA756, "M", "ꝗ"), + (0xA757, "V"), + (0xA758, "M", "ꝙ"), + (0xA759, "V"), + (0xA75A, "M", "ꝛ"), + (0xA75B, "V"), + (0xA75C, "M", "ꝝ"), + (0xA75D, "V"), + (0xA75E, "M", "ꝟ"), + (0xA75F, "V"), + (0xA760, "M", "ꝡ"), + (0xA761, "V"), + (0xA762, "M", "ꝣ"), + (0xA763, "V"), + (0xA764, "M", "ꝥ"), + (0xA765, "V"), + (0xA766, "M", "ꝧ"), + (0xA767, "V"), + (0xA768, "M", "ꝩ"), + (0xA769, "V"), + (0xA76A, "M", "ꝫ"), + (0xA76B, "V"), + (0xA76C, "M", "ꝭ"), + (0xA76D, "V"), + (0xA76E, "M", "ꝯ"), + (0xA76F, "V"), + (0xA770, "M", "ꝯ"), + (0xA771, "V"), + (0xA779, "M", "ꝺ"), + (0xA77A, "V"), + (0xA77B, "M", "ꝼ"), + (0xA77C, "V"), + (0xA77D, "M", "ᵹ"), + (0xA77E, "M", "ꝿ"), + (0xA77F, "V"), + ] + + +def _seg_37() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA780, "M", "ꞁ"), + (0xA781, "V"), + (0xA782, "M", "ꞃ"), + (0xA783, "V"), + (0xA784, "M", "ꞅ"), + (0xA785, "V"), + (0xA786, "M", "ꞇ"), + (0xA787, "V"), + (0xA78B, "M", "ꞌ"), + (0xA78C, "V"), + (0xA78D, "M", "ɥ"), + (0xA78E, "V"), + (0xA790, "M", "ꞑ"), + (0xA791, "V"), + (0xA792, "M", "ꞓ"), + (0xA793, "V"), + (0xA796, "M", "ꞗ"), + (0xA797, "V"), + (0xA798, "M", "ꞙ"), + (0xA799, "V"), + (0xA79A, "M", "ꞛ"), + (0xA79B, "V"), + (0xA79C, "M", "ꞝ"), + (0xA79D, "V"), + (0xA79E, "M", "ꞟ"), + (0xA79F, "V"), + (0xA7A0, "M", "ꞡ"), + (0xA7A1, "V"), + (0xA7A2, "M", "ꞣ"), + (0xA7A3, "V"), + (0xA7A4, "M", "ꞥ"), + (0xA7A5, "V"), + (0xA7A6, "M", "ꞧ"), + (0xA7A7, "V"), + (0xA7A8, "M", "ꞩ"), + (0xA7A9, "V"), + (0xA7AA, "M", "ɦ"), + (0xA7AB, "M", "ɜ"), + (0xA7AC, "M", "ɡ"), + (0xA7AD, "M", "ɬ"), + (0xA7AE, "M", "ɪ"), + (0xA7AF, "V"), + (0xA7B0, "M", "ʞ"), + (0xA7B1, "M", "ʇ"), + (0xA7B2, "M", "ʝ"), + (0xA7B3, "M", "ꭓ"), + (0xA7B4, "M", "ꞵ"), + (0xA7B5, "V"), + (0xA7B6, "M", "ꞷ"), + (0xA7B7, "V"), + (0xA7B8, "M", "ꞹ"), + (0xA7B9, "V"), + (0xA7BA, "M", "ꞻ"), + (0xA7BB, "V"), + (0xA7BC, "M", "ꞽ"), + (0xA7BD, "V"), + (0xA7BE, "M", "ꞿ"), + (0xA7BF, "V"), + (0xA7C0, "M", "ꟁ"), + (0xA7C1, "V"), + (0xA7C2, "M", "ꟃ"), + (0xA7C3, "V"), + (0xA7C4, "M", "ꞔ"), + (0xA7C5, "M", "ʂ"), + (0xA7C6, "M", "ᶎ"), + (0xA7C7, "M", "ꟈ"), + (0xA7C8, "V"), + (0xA7C9, "M", "ꟊ"), + (0xA7CA, "V"), + (0xA7CB, "X"), + (0xA7D0, "M", "ꟑ"), + (0xA7D1, "V"), + (0xA7D2, "X"), + (0xA7D3, "V"), + (0xA7D4, "X"), + (0xA7D5, "V"), + (0xA7D6, "M", "ꟗ"), + (0xA7D7, "V"), + (0xA7D8, "M", "ꟙ"), + (0xA7D9, "V"), + (0xA7DA, "X"), + (0xA7F2, "M", "c"), + (0xA7F3, "M", "f"), + (0xA7F4, "M", "q"), + (0xA7F5, "M", "ꟶ"), + (0xA7F6, "V"), + (0xA7F8, "M", "ħ"), + (0xA7F9, "M", "œ"), + (0xA7FA, "V"), + (0xA82D, "X"), + (0xA830, "V"), + (0xA83A, "X"), + (0xA840, "V"), + (0xA878, "X"), + (0xA880, "V"), + (0xA8C6, "X"), + (0xA8CE, "V"), + (0xA8DA, "X"), + (0xA8E0, "V"), + (0xA954, "X"), + ] + + +def _seg_38() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xA95F, "V"), + (0xA97D, "X"), + (0xA980, "V"), + (0xA9CE, "X"), + (0xA9CF, "V"), + (0xA9DA, "X"), + (0xA9DE, "V"), + (0xA9FF, "X"), + (0xAA00, "V"), + (0xAA37, "X"), + (0xAA40, "V"), + (0xAA4E, "X"), + (0xAA50, "V"), + (0xAA5A, "X"), + (0xAA5C, "V"), + (0xAAC3, "X"), + (0xAADB, "V"), + (0xAAF7, "X"), + (0xAB01, "V"), + (0xAB07, "X"), + (0xAB09, "V"), + (0xAB0F, "X"), + (0xAB11, "V"), + (0xAB17, "X"), + (0xAB20, "V"), + (0xAB27, "X"), + (0xAB28, "V"), + (0xAB2F, "X"), + (0xAB30, "V"), + (0xAB5C, "M", "ꜧ"), + (0xAB5D, "M", "ꬷ"), + (0xAB5E, "M", "ɫ"), + (0xAB5F, "M", "ꭒ"), + (0xAB60, "V"), + (0xAB69, "M", "ʍ"), + (0xAB6A, "V"), + (0xAB6C, "X"), + (0xAB70, "M", "Ꭰ"), + (0xAB71, "M", "Ꭱ"), + (0xAB72, "M", "Ꭲ"), + (0xAB73, "M", "Ꭳ"), + (0xAB74, "M", "Ꭴ"), + (0xAB75, "M", "Ꭵ"), + (0xAB76, "M", "Ꭶ"), + (0xAB77, "M", "Ꭷ"), + (0xAB78, "M", "Ꭸ"), + (0xAB79, "M", "Ꭹ"), + (0xAB7A, "M", "Ꭺ"), + (0xAB7B, "M", "Ꭻ"), + (0xAB7C, "M", "Ꭼ"), + (0xAB7D, "M", "Ꭽ"), + (0xAB7E, "M", "Ꭾ"), + (0xAB7F, "M", "Ꭿ"), + (0xAB80, "M", "Ꮀ"), + (0xAB81, "M", "Ꮁ"), + (0xAB82, "M", "Ꮂ"), + (0xAB83, "M", "Ꮃ"), + (0xAB84, "M", "Ꮄ"), + (0xAB85, "M", "Ꮅ"), + (0xAB86, "M", "Ꮆ"), + (0xAB87, "M", "Ꮇ"), + (0xAB88, "M", "Ꮈ"), + (0xAB89, "M", "Ꮉ"), + (0xAB8A, "M", "Ꮊ"), + (0xAB8B, "M", "Ꮋ"), + (0xAB8C, "M", "Ꮌ"), + (0xAB8D, "M", "Ꮍ"), + (0xAB8E, "M", "Ꮎ"), + (0xAB8F, "M", "Ꮏ"), + (0xAB90, "M", "Ꮐ"), + (0xAB91, "M", "Ꮑ"), + (0xAB92, "M", "Ꮒ"), + (0xAB93, "M", "Ꮓ"), + (0xAB94, "M", "Ꮔ"), + (0xAB95, "M", "Ꮕ"), + (0xAB96, "M", "Ꮖ"), + (0xAB97, "M", "Ꮗ"), + (0xAB98, "M", "Ꮘ"), + (0xAB99, "M", "Ꮙ"), + (0xAB9A, "M", "Ꮚ"), + (0xAB9B, "M", "Ꮛ"), + (0xAB9C, "M", "Ꮜ"), + (0xAB9D, "M", "Ꮝ"), + (0xAB9E, "M", "Ꮞ"), + (0xAB9F, "M", "Ꮟ"), + (0xABA0, "M", "Ꮠ"), + (0xABA1, "M", "Ꮡ"), + (0xABA2, "M", "Ꮢ"), + (0xABA3, "M", "Ꮣ"), + (0xABA4, "M", "Ꮤ"), + (0xABA5, "M", "Ꮥ"), + (0xABA6, "M", "Ꮦ"), + (0xABA7, "M", "Ꮧ"), + (0xABA8, "M", "Ꮨ"), + (0xABA9, "M", "Ꮩ"), + (0xABAA, "M", "Ꮪ"), + (0xABAB, "M", "Ꮫ"), + (0xABAC, "M", "Ꮬ"), + (0xABAD, "M", "Ꮭ"), + (0xABAE, "M", "Ꮮ"), + ] + + +def _seg_39() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xABAF, "M", "Ꮯ"), + (0xABB0, "M", "Ꮰ"), + (0xABB1, "M", "Ꮱ"), + (0xABB2, "M", "Ꮲ"), + (0xABB3, "M", "Ꮳ"), + (0xABB4, "M", "Ꮴ"), + (0xABB5, "M", "Ꮵ"), + (0xABB6, "M", "Ꮶ"), + (0xABB7, "M", "Ꮷ"), + (0xABB8, "M", "Ꮸ"), + (0xABB9, "M", "Ꮹ"), + (0xABBA, "M", "Ꮺ"), + (0xABBB, "M", "Ꮻ"), + (0xABBC, "M", "Ꮼ"), + (0xABBD, "M", "Ꮽ"), + (0xABBE, "M", "Ꮾ"), + (0xABBF, "M", "Ꮿ"), + (0xABC0, "V"), + (0xABEE, "X"), + (0xABF0, "V"), + (0xABFA, "X"), + (0xAC00, "V"), + (0xD7A4, "X"), + (0xD7B0, "V"), + (0xD7C7, "X"), + (0xD7CB, "V"), + (0xD7FC, "X"), + (0xF900, "M", "豈"), + (0xF901, "M", "更"), + (0xF902, "M", "車"), + (0xF903, "M", "賈"), + (0xF904, "M", "滑"), + (0xF905, "M", "串"), + (0xF906, "M", "句"), + (0xF907, "M", "龜"), + (0xF909, "M", "契"), + (0xF90A, "M", "金"), + (0xF90B, "M", "喇"), + (0xF90C, "M", "奈"), + (0xF90D, "M", "懶"), + (0xF90E, "M", "癩"), + (0xF90F, "M", "羅"), + (0xF910, "M", "蘿"), + (0xF911, "M", "螺"), + (0xF912, "M", "裸"), + (0xF913, "M", "邏"), + (0xF914, "M", "樂"), + (0xF915, "M", "洛"), + (0xF916, "M", "烙"), + (0xF917, "M", "珞"), + (0xF918, "M", "落"), + (0xF919, "M", "酪"), + (0xF91A, "M", "駱"), + (0xF91B, "M", "亂"), + (0xF91C, "M", "卵"), + (0xF91D, "M", "欄"), + (0xF91E, "M", "爛"), + (0xF91F, "M", "蘭"), + (0xF920, "M", "鸞"), + (0xF921, "M", "嵐"), + (0xF922, "M", "濫"), + (0xF923, "M", "藍"), + (0xF924, "M", "襤"), + (0xF925, "M", "拉"), + (0xF926, "M", "臘"), + (0xF927, "M", "蠟"), + (0xF928, "M", "廊"), + (0xF929, "M", "朗"), + (0xF92A, "M", "浪"), + (0xF92B, "M", "狼"), + (0xF92C, "M", "郎"), + (0xF92D, "M", "來"), + (0xF92E, "M", "冷"), + (0xF92F, "M", "勞"), + (0xF930, "M", "擄"), + (0xF931, "M", "櫓"), + (0xF932, "M", "爐"), + (0xF933, "M", "盧"), + (0xF934, "M", "老"), + (0xF935, "M", "蘆"), + (0xF936, "M", "虜"), + (0xF937, "M", "路"), + (0xF938, "M", "露"), + (0xF939, "M", "魯"), + (0xF93A, "M", "鷺"), + (0xF93B, "M", "碌"), + (0xF93C, "M", "祿"), + (0xF93D, "M", "綠"), + (0xF93E, "M", "菉"), + (0xF93F, "M", "錄"), + (0xF940, "M", "鹿"), + (0xF941, "M", "論"), + (0xF942, "M", "壟"), + (0xF943, "M", "弄"), + (0xF944, "M", "籠"), + (0xF945, "M", "聾"), + (0xF946, "M", "牢"), + (0xF947, "M", "磊"), + (0xF948, "M", "賂"), + (0xF949, "M", "雷"), + ] + + +def _seg_40() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xF94A, "M", "壘"), + (0xF94B, "M", "屢"), + (0xF94C, "M", "樓"), + (0xF94D, "M", "淚"), + (0xF94E, "M", "漏"), + (0xF94F, "M", "累"), + (0xF950, "M", "縷"), + (0xF951, "M", "陋"), + (0xF952, "M", "勒"), + (0xF953, "M", "肋"), + (0xF954, "M", "凜"), + (0xF955, "M", "凌"), + (0xF956, "M", "稜"), + (0xF957, "M", "綾"), + (0xF958, "M", "菱"), + (0xF959, "M", "陵"), + (0xF95A, "M", "讀"), + (0xF95B, "M", "拏"), + (0xF95C, "M", "樂"), + (0xF95D, "M", "諾"), + (0xF95E, "M", "丹"), + (0xF95F, "M", "寧"), + (0xF960, "M", "怒"), + (0xF961, "M", "率"), + (0xF962, "M", "異"), + (0xF963, "M", "北"), + (0xF964, "M", "磻"), + (0xF965, "M", "便"), + (0xF966, "M", "復"), + (0xF967, "M", "不"), + (0xF968, "M", "泌"), + (0xF969, "M", "數"), + (0xF96A, "M", "索"), + (0xF96B, "M", "參"), + (0xF96C, "M", "塞"), + (0xF96D, "M", "省"), + (0xF96E, "M", "葉"), + (0xF96F, "M", "說"), + (0xF970, "M", "殺"), + (0xF971, "M", "辰"), + (0xF972, "M", "沈"), + (0xF973, "M", "拾"), + (0xF974, "M", "若"), + (0xF975, "M", "掠"), + (0xF976, "M", "略"), + (0xF977, "M", "亮"), + (0xF978, "M", "兩"), + (0xF979, "M", "凉"), + (0xF97A, "M", "梁"), + (0xF97B, "M", "糧"), + (0xF97C, "M", "良"), + (0xF97D, "M", "諒"), + (0xF97E, "M", "量"), + (0xF97F, "M", "勵"), + (0xF980, "M", "呂"), + (0xF981, "M", "女"), + (0xF982, "M", "廬"), + (0xF983, "M", "旅"), + (0xF984, "M", "濾"), + (0xF985, "M", "礪"), + (0xF986, "M", "閭"), + (0xF987, "M", "驪"), + (0xF988, "M", "麗"), + (0xF989, "M", "黎"), + (0xF98A, "M", "力"), + (0xF98B, "M", "曆"), + (0xF98C, "M", "歷"), + (0xF98D, "M", "轢"), + (0xF98E, "M", "年"), + (0xF98F, "M", "憐"), + (0xF990, "M", "戀"), + (0xF991, "M", "撚"), + (0xF992, "M", "漣"), + (0xF993, "M", "煉"), + (0xF994, "M", "璉"), + (0xF995, "M", "秊"), + (0xF996, "M", "練"), + (0xF997, "M", "聯"), + (0xF998, "M", "輦"), + (0xF999, "M", "蓮"), + (0xF99A, "M", "連"), + (0xF99B, "M", "鍊"), + (0xF99C, "M", "列"), + (0xF99D, "M", "劣"), + (0xF99E, "M", "咽"), + (0xF99F, "M", "烈"), + (0xF9A0, "M", "裂"), + (0xF9A1, "M", "說"), + (0xF9A2, "M", "廉"), + (0xF9A3, "M", "念"), + (0xF9A4, "M", "捻"), + (0xF9A5, "M", "殮"), + (0xF9A6, "M", "簾"), + (0xF9A7, "M", "獵"), + (0xF9A8, "M", "令"), + (0xF9A9, "M", "囹"), + (0xF9AA, "M", "寧"), + (0xF9AB, "M", "嶺"), + (0xF9AC, "M", "怜"), + (0xF9AD, "M", "玲"), + ] + + +def _seg_41() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xF9AE, "M", "瑩"), + (0xF9AF, "M", "羚"), + (0xF9B0, "M", "聆"), + (0xF9B1, "M", "鈴"), + (0xF9B2, "M", "零"), + (0xF9B3, "M", "靈"), + (0xF9B4, "M", "領"), + (0xF9B5, "M", "例"), + (0xF9B6, "M", "禮"), + (0xF9B7, "M", "醴"), + (0xF9B8, "M", "隸"), + (0xF9B9, "M", "惡"), + (0xF9BA, "M", "了"), + (0xF9BB, "M", "僚"), + (0xF9BC, "M", "寮"), + (0xF9BD, "M", "尿"), + (0xF9BE, "M", "料"), + (0xF9BF, "M", "樂"), + (0xF9C0, "M", "燎"), + (0xF9C1, "M", "療"), + (0xF9C2, "M", "蓼"), + (0xF9C3, "M", "遼"), + (0xF9C4, "M", "龍"), + (0xF9C5, "M", "暈"), + (0xF9C6, "M", "阮"), + (0xF9C7, "M", "劉"), + (0xF9C8, "M", "杻"), + (0xF9C9, "M", "柳"), + (0xF9CA, "M", "流"), + (0xF9CB, "M", "溜"), + (0xF9CC, "M", "琉"), + (0xF9CD, "M", "留"), + (0xF9CE, "M", "硫"), + (0xF9CF, "M", "紐"), + (0xF9D0, "M", "類"), + (0xF9D1, "M", "六"), + (0xF9D2, "M", "戮"), + (0xF9D3, "M", "陸"), + (0xF9D4, "M", "倫"), + (0xF9D5, "M", "崙"), + (0xF9D6, "M", "淪"), + (0xF9D7, "M", "輪"), + (0xF9D8, "M", "律"), + (0xF9D9, "M", "慄"), + (0xF9DA, "M", "栗"), + (0xF9DB, "M", "率"), + (0xF9DC, "M", "隆"), + (0xF9DD, "M", "利"), + (0xF9DE, "M", "吏"), + (0xF9DF, "M", "履"), + (0xF9E0, "M", "易"), + (0xF9E1, "M", "李"), + (0xF9E2, "M", "梨"), + (0xF9E3, "M", "泥"), + (0xF9E4, "M", "理"), + (0xF9E5, "M", "痢"), + (0xF9E6, "M", "罹"), + (0xF9E7, "M", "裏"), + (0xF9E8, "M", "裡"), + (0xF9E9, "M", "里"), + (0xF9EA, "M", "離"), + (0xF9EB, "M", "匿"), + (0xF9EC, "M", "溺"), + (0xF9ED, "M", "吝"), + (0xF9EE, "M", "燐"), + (0xF9EF, "M", "璘"), + (0xF9F0, "M", "藺"), + (0xF9F1, "M", "隣"), + (0xF9F2, "M", "鱗"), + (0xF9F3, "M", "麟"), + (0xF9F4, "M", "林"), + (0xF9F5, "M", "淋"), + (0xF9F6, "M", "臨"), + (0xF9F7, "M", "立"), + (0xF9F8, "M", "笠"), + (0xF9F9, "M", "粒"), + (0xF9FA, "M", "狀"), + (0xF9FB, "M", "炙"), + (0xF9FC, "M", "識"), + (0xF9FD, "M", "什"), + (0xF9FE, "M", "茶"), + (0xF9FF, "M", "刺"), + (0xFA00, "M", "切"), + (0xFA01, "M", "度"), + (0xFA02, "M", "拓"), + (0xFA03, "M", "糖"), + (0xFA04, "M", "宅"), + (0xFA05, "M", "洞"), + (0xFA06, "M", "暴"), + (0xFA07, "M", "輻"), + (0xFA08, "M", "行"), + (0xFA09, "M", "降"), + (0xFA0A, "M", "見"), + (0xFA0B, "M", "廓"), + (0xFA0C, "M", "兀"), + (0xFA0D, "M", "嗀"), + (0xFA0E, "V"), + (0xFA10, "M", "塚"), + (0xFA11, "V"), + (0xFA12, "M", "晴"), + ] + + +def _seg_42() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFA13, "V"), + (0xFA15, "M", "凞"), + (0xFA16, "M", "猪"), + (0xFA17, "M", "益"), + (0xFA18, "M", "礼"), + (0xFA19, "M", "神"), + (0xFA1A, "M", "祥"), + (0xFA1B, "M", "福"), + (0xFA1C, "M", "靖"), + (0xFA1D, "M", "精"), + (0xFA1E, "M", "羽"), + (0xFA1F, "V"), + (0xFA20, "M", "蘒"), + (0xFA21, "V"), + (0xFA22, "M", "諸"), + (0xFA23, "V"), + (0xFA25, "M", "逸"), + (0xFA26, "M", "都"), + (0xFA27, "V"), + (0xFA2A, "M", "飯"), + (0xFA2B, "M", "飼"), + (0xFA2C, "M", "館"), + (0xFA2D, "M", "鶴"), + (0xFA2E, "M", "郞"), + (0xFA2F, "M", "隷"), + (0xFA30, "M", "侮"), + (0xFA31, "M", "僧"), + (0xFA32, "M", "免"), + (0xFA33, "M", "勉"), + (0xFA34, "M", "勤"), + (0xFA35, "M", "卑"), + (0xFA36, "M", "喝"), + (0xFA37, "M", "嘆"), + (0xFA38, "M", "器"), + (0xFA39, "M", "塀"), + (0xFA3A, "M", "墨"), + (0xFA3B, "M", "層"), + (0xFA3C, "M", "屮"), + (0xFA3D, "M", "悔"), + (0xFA3E, "M", "慨"), + (0xFA3F, "M", "憎"), + (0xFA40, "M", "懲"), + (0xFA41, "M", "敏"), + (0xFA42, "M", "既"), + (0xFA43, "M", "暑"), + (0xFA44, "M", "梅"), + (0xFA45, "M", "海"), + (0xFA46, "M", "渚"), + (0xFA47, "M", "漢"), + (0xFA48, "M", "煮"), + (0xFA49, "M", "爫"), + (0xFA4A, "M", "琢"), + (0xFA4B, "M", "碑"), + (0xFA4C, "M", "社"), + (0xFA4D, "M", "祉"), + (0xFA4E, "M", "祈"), + (0xFA4F, "M", "祐"), + (0xFA50, "M", "祖"), + (0xFA51, "M", "祝"), + (0xFA52, "M", "禍"), + (0xFA53, "M", "禎"), + (0xFA54, "M", "穀"), + (0xFA55, "M", "突"), + (0xFA56, "M", "節"), + (0xFA57, "M", "練"), + (0xFA58, "M", "縉"), + (0xFA59, "M", "繁"), + (0xFA5A, "M", "署"), + (0xFA5B, "M", "者"), + (0xFA5C, "M", "臭"), + (0xFA5D, "M", "艹"), + (0xFA5F, "M", "著"), + (0xFA60, "M", "褐"), + (0xFA61, "M", "視"), + (0xFA62, "M", "謁"), + (0xFA63, "M", "謹"), + (0xFA64, "M", "賓"), + (0xFA65, "M", "贈"), + (0xFA66, "M", "辶"), + (0xFA67, "M", "逸"), + (0xFA68, "M", "難"), + (0xFA69, "M", "響"), + (0xFA6A, "M", "頻"), + (0xFA6B, "M", "恵"), + (0xFA6C, "M", "𤋮"), + (0xFA6D, "M", "舘"), + (0xFA6E, "X"), + (0xFA70, "M", "並"), + (0xFA71, "M", "况"), + (0xFA72, "M", "全"), + (0xFA73, "M", "侀"), + (0xFA74, "M", "充"), + (0xFA75, "M", "冀"), + (0xFA76, "M", "勇"), + (0xFA77, "M", "勺"), + (0xFA78, "M", "喝"), + (0xFA79, "M", "啕"), + (0xFA7A, "M", "喙"), + (0xFA7B, "M", "嗢"), + (0xFA7C, "M", "塚"), + ] + + +def _seg_43() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFA7D, "M", "墳"), + (0xFA7E, "M", "奄"), + (0xFA7F, "M", "奔"), + (0xFA80, "M", "婢"), + (0xFA81, "M", "嬨"), + (0xFA82, "M", "廒"), + (0xFA83, "M", "廙"), + (0xFA84, "M", "彩"), + (0xFA85, "M", "徭"), + (0xFA86, "M", "惘"), + (0xFA87, "M", "慎"), + (0xFA88, "M", "愈"), + (0xFA89, "M", "憎"), + (0xFA8A, "M", "慠"), + (0xFA8B, "M", "懲"), + (0xFA8C, "M", "戴"), + (0xFA8D, "M", "揄"), + (0xFA8E, "M", "搜"), + (0xFA8F, "M", "摒"), + (0xFA90, "M", "敖"), + (0xFA91, "M", "晴"), + (0xFA92, "M", "朗"), + (0xFA93, "M", "望"), + (0xFA94, "M", "杖"), + (0xFA95, "M", "歹"), + (0xFA96, "M", "殺"), + (0xFA97, "M", "流"), + (0xFA98, "M", "滛"), + (0xFA99, "M", "滋"), + (0xFA9A, "M", "漢"), + (0xFA9B, "M", "瀞"), + (0xFA9C, "M", "煮"), + (0xFA9D, "M", "瞧"), + (0xFA9E, "M", "爵"), + (0xFA9F, "M", "犯"), + (0xFAA0, "M", "猪"), + (0xFAA1, "M", "瑱"), + (0xFAA2, "M", "甆"), + (0xFAA3, "M", "画"), + (0xFAA4, "M", "瘝"), + (0xFAA5, "M", "瘟"), + (0xFAA6, "M", "益"), + (0xFAA7, "M", "盛"), + (0xFAA8, "M", "直"), + (0xFAA9, "M", "睊"), + (0xFAAA, "M", "着"), + (0xFAAB, "M", "磌"), + (0xFAAC, "M", "窱"), + (0xFAAD, "M", "節"), + (0xFAAE, "M", "类"), + (0xFAAF, "M", "絛"), + (0xFAB0, "M", "練"), + (0xFAB1, "M", "缾"), + (0xFAB2, "M", "者"), + (0xFAB3, "M", "荒"), + (0xFAB4, "M", "華"), + (0xFAB5, "M", "蝹"), + (0xFAB6, "M", "襁"), + (0xFAB7, "M", "覆"), + (0xFAB8, "M", "視"), + (0xFAB9, "M", "調"), + (0xFABA, "M", "諸"), + (0xFABB, "M", "請"), + (0xFABC, "M", "謁"), + (0xFABD, "M", "諾"), + (0xFABE, "M", "諭"), + (0xFABF, "M", "謹"), + (0xFAC0, "M", "變"), + (0xFAC1, "M", "贈"), + (0xFAC2, "M", "輸"), + (0xFAC3, "M", "遲"), + (0xFAC4, "M", "醙"), + (0xFAC5, "M", "鉶"), + (0xFAC6, "M", "陼"), + (0xFAC7, "M", "難"), + (0xFAC8, "M", "靖"), + (0xFAC9, "M", "韛"), + (0xFACA, "M", "響"), + (0xFACB, "M", "頋"), + (0xFACC, "M", "頻"), + (0xFACD, "M", "鬒"), + (0xFACE, "M", "龜"), + (0xFACF, "M", "𢡊"), + (0xFAD0, "M", "𢡄"), + (0xFAD1, "M", "𣏕"), + (0xFAD2, "M", "㮝"), + (0xFAD3, "M", "䀘"), + (0xFAD4, "M", "䀹"), + (0xFAD5, "M", "𥉉"), + (0xFAD6, "M", "𥳐"), + (0xFAD7, "M", "𧻓"), + (0xFAD8, "M", "齃"), + (0xFAD9, "M", "龎"), + (0xFADA, "X"), + (0xFB00, "M", "ff"), + (0xFB01, "M", "fi"), + (0xFB02, "M", "fl"), + (0xFB03, "M", "ffi"), + (0xFB04, "M", "ffl"), + (0xFB05, "M", "st"), + ] + + +def _seg_44() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFB07, "X"), + (0xFB13, "M", "մն"), + (0xFB14, "M", "մե"), + (0xFB15, "M", "մի"), + (0xFB16, "M", "վն"), + (0xFB17, "M", "մխ"), + (0xFB18, "X"), + (0xFB1D, "M", "יִ"), + (0xFB1E, "V"), + (0xFB1F, "M", "ײַ"), + (0xFB20, "M", "ע"), + (0xFB21, "M", "א"), + (0xFB22, "M", "ד"), + (0xFB23, "M", "ה"), + (0xFB24, "M", "כ"), + (0xFB25, "M", "ל"), + (0xFB26, "M", "ם"), + (0xFB27, "M", "ר"), + (0xFB28, "M", "ת"), + (0xFB29, "3", "+"), + (0xFB2A, "M", "שׁ"), + (0xFB2B, "M", "שׂ"), + (0xFB2C, "M", "שּׁ"), + (0xFB2D, "M", "שּׂ"), + (0xFB2E, "M", "אַ"), + (0xFB2F, "M", "אָ"), + (0xFB30, "M", "אּ"), + (0xFB31, "M", "בּ"), + (0xFB32, "M", "גּ"), + (0xFB33, "M", "דּ"), + (0xFB34, "M", "הּ"), + (0xFB35, "M", "וּ"), + (0xFB36, "M", "זּ"), + (0xFB37, "X"), + (0xFB38, "M", "טּ"), + (0xFB39, "M", "יּ"), + (0xFB3A, "M", "ךּ"), + (0xFB3B, "M", "כּ"), + (0xFB3C, "M", "לּ"), + (0xFB3D, "X"), + (0xFB3E, "M", "מּ"), + (0xFB3F, "X"), + (0xFB40, "M", "נּ"), + (0xFB41, "M", "סּ"), + (0xFB42, "X"), + (0xFB43, "M", "ףּ"), + (0xFB44, "M", "פּ"), + (0xFB45, "X"), + (0xFB46, "M", "צּ"), + (0xFB47, "M", "קּ"), + (0xFB48, "M", "רּ"), + (0xFB49, "M", "שּ"), + (0xFB4A, "M", "תּ"), + (0xFB4B, "M", "וֹ"), + (0xFB4C, "M", "בֿ"), + (0xFB4D, "M", "כֿ"), + (0xFB4E, "M", "פֿ"), + (0xFB4F, "M", "אל"), + (0xFB50, "M", "ٱ"), + (0xFB52, "M", "ٻ"), + (0xFB56, "M", "پ"), + (0xFB5A, "M", "ڀ"), + (0xFB5E, "M", "ٺ"), + (0xFB62, "M", "ٿ"), + (0xFB66, "M", "ٹ"), + (0xFB6A, "M", "ڤ"), + (0xFB6E, "M", "ڦ"), + (0xFB72, "M", "ڄ"), + (0xFB76, "M", "ڃ"), + (0xFB7A, "M", "چ"), + (0xFB7E, "M", "ڇ"), + (0xFB82, "M", "ڍ"), + (0xFB84, "M", "ڌ"), + (0xFB86, "M", "ڎ"), + (0xFB88, "M", "ڈ"), + (0xFB8A, "M", "ژ"), + (0xFB8C, "M", "ڑ"), + (0xFB8E, "M", "ک"), + (0xFB92, "M", "گ"), + (0xFB96, "M", "ڳ"), + (0xFB9A, "M", "ڱ"), + (0xFB9E, "M", "ں"), + (0xFBA0, "M", "ڻ"), + (0xFBA4, "M", "ۀ"), + (0xFBA6, "M", "ہ"), + (0xFBAA, "M", "ھ"), + (0xFBAE, "M", "ے"), + (0xFBB0, "M", "ۓ"), + (0xFBB2, "V"), + (0xFBC3, "X"), + (0xFBD3, "M", "ڭ"), + (0xFBD7, "M", "ۇ"), + (0xFBD9, "M", "ۆ"), + (0xFBDB, "M", "ۈ"), + (0xFBDD, "M", "ۇٴ"), + (0xFBDE, "M", "ۋ"), + (0xFBE0, "M", "ۅ"), + (0xFBE2, "M", "ۉ"), + (0xFBE4, "M", "ې"), + (0xFBE8, "M", "ى"), + ] + + +def _seg_45() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFBEA, "M", "ئا"), + (0xFBEC, "M", "ئە"), + (0xFBEE, "M", "ئو"), + (0xFBF0, "M", "ئۇ"), + (0xFBF2, "M", "ئۆ"), + (0xFBF4, "M", "ئۈ"), + (0xFBF6, "M", "ئې"), + (0xFBF9, "M", "ئى"), + (0xFBFC, "M", "ی"), + (0xFC00, "M", "ئج"), + (0xFC01, "M", "ئح"), + (0xFC02, "M", "ئم"), + (0xFC03, "M", "ئى"), + (0xFC04, "M", "ئي"), + (0xFC05, "M", "بج"), + (0xFC06, "M", "بح"), + (0xFC07, "M", "بخ"), + (0xFC08, "M", "بم"), + (0xFC09, "M", "بى"), + (0xFC0A, "M", "بي"), + (0xFC0B, "M", "تج"), + (0xFC0C, "M", "تح"), + (0xFC0D, "M", "تخ"), + (0xFC0E, "M", "تم"), + (0xFC0F, "M", "تى"), + (0xFC10, "M", "تي"), + (0xFC11, "M", "ثج"), + (0xFC12, "M", "ثم"), + (0xFC13, "M", "ثى"), + (0xFC14, "M", "ثي"), + (0xFC15, "M", "جح"), + (0xFC16, "M", "جم"), + (0xFC17, "M", "حج"), + (0xFC18, "M", "حم"), + (0xFC19, "M", "خج"), + (0xFC1A, "M", "خح"), + (0xFC1B, "M", "خم"), + (0xFC1C, "M", "سج"), + (0xFC1D, "M", "سح"), + (0xFC1E, "M", "سخ"), + (0xFC1F, "M", "سم"), + (0xFC20, "M", "صح"), + (0xFC21, "M", "صم"), + (0xFC22, "M", "ضج"), + (0xFC23, "M", "ضح"), + (0xFC24, "M", "ضخ"), + (0xFC25, "M", "ضم"), + (0xFC26, "M", "طح"), + (0xFC27, "M", "طم"), + (0xFC28, "M", "ظم"), + (0xFC29, "M", "عج"), + (0xFC2A, "M", "عم"), + (0xFC2B, "M", "غج"), + (0xFC2C, "M", "غم"), + (0xFC2D, "M", "فج"), + (0xFC2E, "M", "فح"), + (0xFC2F, "M", "فخ"), + (0xFC30, "M", "فم"), + (0xFC31, "M", "فى"), + (0xFC32, "M", "في"), + (0xFC33, "M", "قح"), + (0xFC34, "M", "قم"), + (0xFC35, "M", "قى"), + (0xFC36, "M", "قي"), + (0xFC37, "M", "كا"), + (0xFC38, "M", "كج"), + (0xFC39, "M", "كح"), + (0xFC3A, "M", "كخ"), + (0xFC3B, "M", "كل"), + (0xFC3C, "M", "كم"), + (0xFC3D, "M", "كى"), + (0xFC3E, "M", "كي"), + (0xFC3F, "M", "لج"), + (0xFC40, "M", "لح"), + (0xFC41, "M", "لخ"), + (0xFC42, "M", "لم"), + (0xFC43, "M", "لى"), + (0xFC44, "M", "لي"), + (0xFC45, "M", "مج"), + (0xFC46, "M", "مح"), + (0xFC47, "M", "مخ"), + (0xFC48, "M", "مم"), + (0xFC49, "M", "مى"), + (0xFC4A, "M", "مي"), + (0xFC4B, "M", "نج"), + (0xFC4C, "M", "نح"), + (0xFC4D, "M", "نخ"), + (0xFC4E, "M", "نم"), + (0xFC4F, "M", "نى"), + (0xFC50, "M", "ني"), + (0xFC51, "M", "هج"), + (0xFC52, "M", "هم"), + (0xFC53, "M", "هى"), + (0xFC54, "M", "هي"), + (0xFC55, "M", "يج"), + (0xFC56, "M", "يح"), + (0xFC57, "M", "يخ"), + (0xFC58, "M", "يم"), + (0xFC59, "M", "يى"), + (0xFC5A, "M", "يي"), + ] + + +def _seg_46() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFC5B, "M", "ذٰ"), + (0xFC5C, "M", "رٰ"), + (0xFC5D, "M", "ىٰ"), + (0xFC5E, "3", " ٌّ"), + (0xFC5F, "3", " ٍّ"), + (0xFC60, "3", " َّ"), + (0xFC61, "3", " ُّ"), + (0xFC62, "3", " ِّ"), + (0xFC63, "3", " ّٰ"), + (0xFC64, "M", "ئر"), + (0xFC65, "M", "ئز"), + (0xFC66, "M", "ئم"), + (0xFC67, "M", "ئن"), + (0xFC68, "M", "ئى"), + (0xFC69, "M", "ئي"), + (0xFC6A, "M", "بر"), + (0xFC6B, "M", "بز"), + (0xFC6C, "M", "بم"), + (0xFC6D, "M", "بن"), + (0xFC6E, "M", "بى"), + (0xFC6F, "M", "بي"), + (0xFC70, "M", "تر"), + (0xFC71, "M", "تز"), + (0xFC72, "M", "تم"), + (0xFC73, "M", "تن"), + (0xFC74, "M", "تى"), + (0xFC75, "M", "تي"), + (0xFC76, "M", "ثر"), + (0xFC77, "M", "ثز"), + (0xFC78, "M", "ثم"), + (0xFC79, "M", "ثن"), + (0xFC7A, "M", "ثى"), + (0xFC7B, "M", "ثي"), + (0xFC7C, "M", "فى"), + (0xFC7D, "M", "في"), + (0xFC7E, "M", "قى"), + (0xFC7F, "M", "قي"), + (0xFC80, "M", "كا"), + (0xFC81, "M", "كل"), + (0xFC82, "M", "كم"), + (0xFC83, "M", "كى"), + (0xFC84, "M", "كي"), + (0xFC85, "M", "لم"), + (0xFC86, "M", "لى"), + (0xFC87, "M", "لي"), + (0xFC88, "M", "ما"), + (0xFC89, "M", "مم"), + (0xFC8A, "M", "نر"), + (0xFC8B, "M", "نز"), + (0xFC8C, "M", "نم"), + (0xFC8D, "M", "نن"), + (0xFC8E, "M", "نى"), + (0xFC8F, "M", "ني"), + (0xFC90, "M", "ىٰ"), + (0xFC91, "M", "ير"), + (0xFC92, "M", "يز"), + (0xFC93, "M", "يم"), + (0xFC94, "M", "ين"), + (0xFC95, "M", "يى"), + (0xFC96, "M", "يي"), + (0xFC97, "M", "ئج"), + (0xFC98, "M", "ئح"), + (0xFC99, "M", "ئخ"), + (0xFC9A, "M", "ئم"), + (0xFC9B, "M", "ئه"), + (0xFC9C, "M", "بج"), + (0xFC9D, "M", "بح"), + (0xFC9E, "M", "بخ"), + (0xFC9F, "M", "بم"), + (0xFCA0, "M", "به"), + (0xFCA1, "M", "تج"), + (0xFCA2, "M", "تح"), + (0xFCA3, "M", "تخ"), + (0xFCA4, "M", "تم"), + (0xFCA5, "M", "ته"), + (0xFCA6, "M", "ثم"), + (0xFCA7, "M", "جح"), + (0xFCA8, "M", "جم"), + (0xFCA9, "M", "حج"), + (0xFCAA, "M", "حم"), + (0xFCAB, "M", "خج"), + (0xFCAC, "M", "خم"), + (0xFCAD, "M", "سج"), + (0xFCAE, "M", "سح"), + (0xFCAF, "M", "سخ"), + (0xFCB0, "M", "سم"), + (0xFCB1, "M", "صح"), + (0xFCB2, "M", "صخ"), + (0xFCB3, "M", "صم"), + (0xFCB4, "M", "ضج"), + (0xFCB5, "M", "ضح"), + (0xFCB6, "M", "ضخ"), + (0xFCB7, "M", "ضم"), + (0xFCB8, "M", "طح"), + (0xFCB9, "M", "ظم"), + (0xFCBA, "M", "عج"), + (0xFCBB, "M", "عم"), + (0xFCBC, "M", "غج"), + (0xFCBD, "M", "غم"), + (0xFCBE, "M", "فج"), + ] + + +def _seg_47() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFCBF, "M", "فح"), + (0xFCC0, "M", "فخ"), + (0xFCC1, "M", "فم"), + (0xFCC2, "M", "قح"), + (0xFCC3, "M", "قم"), + (0xFCC4, "M", "كج"), + (0xFCC5, "M", "كح"), + (0xFCC6, "M", "كخ"), + (0xFCC7, "M", "كل"), + (0xFCC8, "M", "كم"), + (0xFCC9, "M", "لج"), + (0xFCCA, "M", "لح"), + (0xFCCB, "M", "لخ"), + (0xFCCC, "M", "لم"), + (0xFCCD, "M", "له"), + (0xFCCE, "M", "مج"), + (0xFCCF, "M", "مح"), + (0xFCD0, "M", "مخ"), + (0xFCD1, "M", "مم"), + (0xFCD2, "M", "نج"), + (0xFCD3, "M", "نح"), + (0xFCD4, "M", "نخ"), + (0xFCD5, "M", "نم"), + (0xFCD6, "M", "نه"), + (0xFCD7, "M", "هج"), + (0xFCD8, "M", "هم"), + (0xFCD9, "M", "هٰ"), + (0xFCDA, "M", "يج"), + (0xFCDB, "M", "يح"), + (0xFCDC, "M", "يخ"), + (0xFCDD, "M", "يم"), + (0xFCDE, "M", "يه"), + (0xFCDF, "M", "ئم"), + (0xFCE0, "M", "ئه"), + (0xFCE1, "M", "بم"), + (0xFCE2, "M", "به"), + (0xFCE3, "M", "تم"), + (0xFCE4, "M", "ته"), + (0xFCE5, "M", "ثم"), + (0xFCE6, "M", "ثه"), + (0xFCE7, "M", "سم"), + (0xFCE8, "M", "سه"), + (0xFCE9, "M", "شم"), + (0xFCEA, "M", "شه"), + (0xFCEB, "M", "كل"), + (0xFCEC, "M", "كم"), + (0xFCED, "M", "لم"), + (0xFCEE, "M", "نم"), + (0xFCEF, "M", "نه"), + (0xFCF0, "M", "يم"), + (0xFCF1, "M", "يه"), + (0xFCF2, "M", "ـَّ"), + (0xFCF3, "M", "ـُّ"), + (0xFCF4, "M", "ـِّ"), + (0xFCF5, "M", "طى"), + (0xFCF6, "M", "طي"), + (0xFCF7, "M", "عى"), + (0xFCF8, "M", "عي"), + (0xFCF9, "M", "غى"), + (0xFCFA, "M", "غي"), + (0xFCFB, "M", "سى"), + (0xFCFC, "M", "سي"), + (0xFCFD, "M", "شى"), + (0xFCFE, "M", "شي"), + (0xFCFF, "M", "حى"), + (0xFD00, "M", "حي"), + (0xFD01, "M", "جى"), + (0xFD02, "M", "جي"), + (0xFD03, "M", "خى"), + (0xFD04, "M", "خي"), + (0xFD05, "M", "صى"), + (0xFD06, "M", "صي"), + (0xFD07, "M", "ضى"), + (0xFD08, "M", "ضي"), + (0xFD09, "M", "شج"), + (0xFD0A, "M", "شح"), + (0xFD0B, "M", "شخ"), + (0xFD0C, "M", "شم"), + (0xFD0D, "M", "شر"), + (0xFD0E, "M", "سر"), + (0xFD0F, "M", "صر"), + (0xFD10, "M", "ضر"), + (0xFD11, "M", "طى"), + (0xFD12, "M", "طي"), + (0xFD13, "M", "عى"), + (0xFD14, "M", "عي"), + (0xFD15, "M", "غى"), + (0xFD16, "M", "غي"), + (0xFD17, "M", "سى"), + (0xFD18, "M", "سي"), + (0xFD19, "M", "شى"), + (0xFD1A, "M", "شي"), + (0xFD1B, "M", "حى"), + (0xFD1C, "M", "حي"), + (0xFD1D, "M", "جى"), + (0xFD1E, "M", "جي"), + (0xFD1F, "M", "خى"), + (0xFD20, "M", "خي"), + (0xFD21, "M", "صى"), + (0xFD22, "M", "صي"), + ] + + +def _seg_48() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFD23, "M", "ضى"), + (0xFD24, "M", "ضي"), + (0xFD25, "M", "شج"), + (0xFD26, "M", "شح"), + (0xFD27, "M", "شخ"), + (0xFD28, "M", "شم"), + (0xFD29, "M", "شر"), + (0xFD2A, "M", "سر"), + (0xFD2B, "M", "صر"), + (0xFD2C, "M", "ضر"), + (0xFD2D, "M", "شج"), + (0xFD2E, "M", "شح"), + (0xFD2F, "M", "شخ"), + (0xFD30, "M", "شم"), + (0xFD31, "M", "سه"), + (0xFD32, "M", "شه"), + (0xFD33, "M", "طم"), + (0xFD34, "M", "سج"), + (0xFD35, "M", "سح"), + (0xFD36, "M", "سخ"), + (0xFD37, "M", "شج"), + (0xFD38, "M", "شح"), + (0xFD39, "M", "شخ"), + (0xFD3A, "M", "طم"), + (0xFD3B, "M", "ظم"), + (0xFD3C, "M", "اً"), + (0xFD3E, "V"), + (0xFD50, "M", "تجم"), + (0xFD51, "M", "تحج"), + (0xFD53, "M", "تحم"), + (0xFD54, "M", "تخم"), + (0xFD55, "M", "تمج"), + (0xFD56, "M", "تمح"), + (0xFD57, "M", "تمخ"), + (0xFD58, "M", "جمح"), + (0xFD5A, "M", "حمي"), + (0xFD5B, "M", "حمى"), + (0xFD5C, "M", "سحج"), + (0xFD5D, "M", "سجح"), + (0xFD5E, "M", "سجى"), + (0xFD5F, "M", "سمح"), + (0xFD61, "M", "سمج"), + (0xFD62, "M", "سمم"), + (0xFD64, "M", "صحح"), + (0xFD66, "M", "صمم"), + (0xFD67, "M", "شحم"), + (0xFD69, "M", "شجي"), + (0xFD6A, "M", "شمخ"), + (0xFD6C, "M", "شمم"), + (0xFD6E, "M", "ضحى"), + (0xFD6F, "M", "ضخم"), + (0xFD71, "M", "طمح"), + (0xFD73, "M", "طمم"), + (0xFD74, "M", "طمي"), + (0xFD75, "M", "عجم"), + (0xFD76, "M", "عمم"), + (0xFD78, "M", "عمى"), + (0xFD79, "M", "غمم"), + (0xFD7A, "M", "غمي"), + (0xFD7B, "M", "غمى"), + (0xFD7C, "M", "فخم"), + (0xFD7E, "M", "قمح"), + (0xFD7F, "M", "قمم"), + (0xFD80, "M", "لحم"), + (0xFD81, "M", "لحي"), + (0xFD82, "M", "لحى"), + (0xFD83, "M", "لجج"), + (0xFD85, "M", "لخم"), + (0xFD87, "M", "لمح"), + (0xFD89, "M", "محج"), + (0xFD8A, "M", "محم"), + (0xFD8B, "M", "محي"), + (0xFD8C, "M", "مجح"), + (0xFD8D, "M", "مجم"), + (0xFD8E, "M", "مخج"), + (0xFD8F, "M", "مخم"), + (0xFD90, "X"), + (0xFD92, "M", "مجخ"), + (0xFD93, "M", "همج"), + (0xFD94, "M", "همم"), + (0xFD95, "M", "نحم"), + (0xFD96, "M", "نحى"), + (0xFD97, "M", "نجم"), + (0xFD99, "M", "نجى"), + (0xFD9A, "M", "نمي"), + (0xFD9B, "M", "نمى"), + (0xFD9C, "M", "يمم"), + (0xFD9E, "M", "بخي"), + (0xFD9F, "M", "تجي"), + (0xFDA0, "M", "تجى"), + (0xFDA1, "M", "تخي"), + (0xFDA2, "M", "تخى"), + (0xFDA3, "M", "تمي"), + (0xFDA4, "M", "تمى"), + (0xFDA5, "M", "جمي"), + (0xFDA6, "M", "جحى"), + (0xFDA7, "M", "جمى"), + (0xFDA8, "M", "سخى"), + (0xFDA9, "M", "صحي"), + (0xFDAA, "M", "شحي"), + ] + + +def _seg_49() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFDAB, "M", "ضحي"), + (0xFDAC, "M", "لجي"), + (0xFDAD, "M", "لمي"), + (0xFDAE, "M", "يحي"), + (0xFDAF, "M", "يجي"), + (0xFDB0, "M", "يمي"), + (0xFDB1, "M", "ممي"), + (0xFDB2, "M", "قمي"), + (0xFDB3, "M", "نحي"), + (0xFDB4, "M", "قمح"), + (0xFDB5, "M", "لحم"), + (0xFDB6, "M", "عمي"), + (0xFDB7, "M", "كمي"), + (0xFDB8, "M", "نجح"), + (0xFDB9, "M", "مخي"), + (0xFDBA, "M", "لجم"), + (0xFDBB, "M", "كمم"), + (0xFDBC, "M", "لجم"), + (0xFDBD, "M", "نجح"), + (0xFDBE, "M", "جحي"), + (0xFDBF, "M", "حجي"), + (0xFDC0, "M", "مجي"), + (0xFDC1, "M", "فمي"), + (0xFDC2, "M", "بحي"), + (0xFDC3, "M", "كمم"), + (0xFDC4, "M", "عجم"), + (0xFDC5, "M", "صمم"), + (0xFDC6, "M", "سخي"), + (0xFDC7, "M", "نجي"), + (0xFDC8, "X"), + (0xFDCF, "V"), + (0xFDD0, "X"), + (0xFDF0, "M", "صلے"), + (0xFDF1, "M", "قلے"), + (0xFDF2, "M", "الله"), + (0xFDF3, "M", "اكبر"), + (0xFDF4, "M", "محمد"), + (0xFDF5, "M", "صلعم"), + (0xFDF6, "M", "رسول"), + (0xFDF7, "M", "عليه"), + (0xFDF8, "M", "وسلم"), + (0xFDF9, "M", "صلى"), + (0xFDFA, "3", "صلى الله عليه وسلم"), + (0xFDFB, "3", "جل جلاله"), + (0xFDFC, "M", "ریال"), + (0xFDFD, "V"), + (0xFE00, "I"), + (0xFE10, "3", ","), + (0xFE11, "M", "、"), + (0xFE12, "X"), + (0xFE13, "3", ":"), + (0xFE14, "3", ";"), + (0xFE15, "3", "!"), + (0xFE16, "3", "?"), + (0xFE17, "M", "〖"), + (0xFE18, "M", "〗"), + (0xFE19, "X"), + (0xFE20, "V"), + (0xFE30, "X"), + (0xFE31, "M", "—"), + (0xFE32, "M", "–"), + (0xFE33, "3", "_"), + (0xFE35, "3", "("), + (0xFE36, "3", ")"), + (0xFE37, "3", "{"), + (0xFE38, "3", "}"), + (0xFE39, "M", "〔"), + (0xFE3A, "M", "〕"), + (0xFE3B, "M", "【"), + (0xFE3C, "M", "】"), + (0xFE3D, "M", "《"), + (0xFE3E, "M", "》"), + (0xFE3F, "M", "〈"), + (0xFE40, "M", "〉"), + (0xFE41, "M", "「"), + (0xFE42, "M", "」"), + (0xFE43, "M", "『"), + (0xFE44, "M", "』"), + (0xFE45, "V"), + (0xFE47, "3", "["), + (0xFE48, "3", "]"), + (0xFE49, "3", " ̅"), + (0xFE4D, "3", "_"), + (0xFE50, "3", ","), + (0xFE51, "M", "、"), + (0xFE52, "X"), + (0xFE54, "3", ";"), + (0xFE55, "3", ":"), + (0xFE56, "3", "?"), + (0xFE57, "3", "!"), + (0xFE58, "M", "—"), + (0xFE59, "3", "("), + (0xFE5A, "3", ")"), + (0xFE5B, "3", "{"), + (0xFE5C, "3", "}"), + (0xFE5D, "M", "〔"), + (0xFE5E, "M", "〕"), + (0xFE5F, "3", "#"), + (0xFE60, "3", "&"), + (0xFE61, "3", "*"), + ] + + +def _seg_50() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFE62, "3", "+"), + (0xFE63, "M", "-"), + (0xFE64, "3", "<"), + (0xFE65, "3", ">"), + (0xFE66, "3", "="), + (0xFE67, "X"), + (0xFE68, "3", "\\"), + (0xFE69, "3", "$"), + (0xFE6A, "3", "%"), + (0xFE6B, "3", "@"), + (0xFE6C, "X"), + (0xFE70, "3", " ً"), + (0xFE71, "M", "ـً"), + (0xFE72, "3", " ٌ"), + (0xFE73, "V"), + (0xFE74, "3", " ٍ"), + (0xFE75, "X"), + (0xFE76, "3", " َ"), + (0xFE77, "M", "ـَ"), + (0xFE78, "3", " ُ"), + (0xFE79, "M", "ـُ"), + (0xFE7A, "3", " ِ"), + (0xFE7B, "M", "ـِ"), + (0xFE7C, "3", " ّ"), + (0xFE7D, "M", "ـّ"), + (0xFE7E, "3", " ْ"), + (0xFE7F, "M", "ـْ"), + (0xFE80, "M", "ء"), + (0xFE81, "M", "آ"), + (0xFE83, "M", "أ"), + (0xFE85, "M", "ؤ"), + (0xFE87, "M", "إ"), + (0xFE89, "M", "ئ"), + (0xFE8D, "M", "ا"), + (0xFE8F, "M", "ب"), + (0xFE93, "M", "ة"), + (0xFE95, "M", "ت"), + (0xFE99, "M", "ث"), + (0xFE9D, "M", "ج"), + (0xFEA1, "M", "ح"), + (0xFEA5, "M", "خ"), + (0xFEA9, "M", "د"), + (0xFEAB, "M", "ذ"), + (0xFEAD, "M", "ر"), + (0xFEAF, "M", "ز"), + (0xFEB1, "M", "س"), + (0xFEB5, "M", "ش"), + (0xFEB9, "M", "ص"), + (0xFEBD, "M", "ض"), + (0xFEC1, "M", "ط"), + (0xFEC5, "M", "ظ"), + (0xFEC9, "M", "ع"), + (0xFECD, "M", "غ"), + (0xFED1, "M", "ف"), + (0xFED5, "M", "ق"), + (0xFED9, "M", "ك"), + (0xFEDD, "M", "ل"), + (0xFEE1, "M", "م"), + (0xFEE5, "M", "ن"), + (0xFEE9, "M", "ه"), + (0xFEED, "M", "و"), + (0xFEEF, "M", "ى"), + (0xFEF1, "M", "ي"), + (0xFEF5, "M", "لآ"), + (0xFEF7, "M", "لأ"), + (0xFEF9, "M", "لإ"), + (0xFEFB, "M", "لا"), + (0xFEFD, "X"), + (0xFEFF, "I"), + (0xFF00, "X"), + (0xFF01, "3", "!"), + (0xFF02, "3", '"'), + (0xFF03, "3", "#"), + (0xFF04, "3", "$"), + (0xFF05, "3", "%"), + (0xFF06, "3", "&"), + (0xFF07, "3", "'"), + (0xFF08, "3", "("), + (0xFF09, "3", ")"), + (0xFF0A, "3", "*"), + (0xFF0B, "3", "+"), + (0xFF0C, "3", ","), + (0xFF0D, "M", "-"), + (0xFF0E, "M", "."), + (0xFF0F, "3", "/"), + (0xFF10, "M", "0"), + (0xFF11, "M", "1"), + (0xFF12, "M", "2"), + (0xFF13, "M", "3"), + (0xFF14, "M", "4"), + (0xFF15, "M", "5"), + (0xFF16, "M", "6"), + (0xFF17, "M", "7"), + (0xFF18, "M", "8"), + (0xFF19, "M", "9"), + (0xFF1A, "3", ":"), + (0xFF1B, "3", ";"), + (0xFF1C, "3", "<"), + (0xFF1D, "3", "="), + (0xFF1E, "3", ">"), + ] + + +def _seg_51() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFF1F, "3", "?"), + (0xFF20, "3", "@"), + (0xFF21, "M", "a"), + (0xFF22, "M", "b"), + (0xFF23, "M", "c"), + (0xFF24, "M", "d"), + (0xFF25, "M", "e"), + (0xFF26, "M", "f"), + (0xFF27, "M", "g"), + (0xFF28, "M", "h"), + (0xFF29, "M", "i"), + (0xFF2A, "M", "j"), + (0xFF2B, "M", "k"), + (0xFF2C, "M", "l"), + (0xFF2D, "M", "m"), + (0xFF2E, "M", "n"), + (0xFF2F, "M", "o"), + (0xFF30, "M", "p"), + (0xFF31, "M", "q"), + (0xFF32, "M", "r"), + (0xFF33, "M", "s"), + (0xFF34, "M", "t"), + (0xFF35, "M", "u"), + (0xFF36, "M", "v"), + (0xFF37, "M", "w"), + (0xFF38, "M", "x"), + (0xFF39, "M", "y"), + (0xFF3A, "M", "z"), + (0xFF3B, "3", "["), + (0xFF3C, "3", "\\"), + (0xFF3D, "3", "]"), + (0xFF3E, "3", "^"), + (0xFF3F, "3", "_"), + (0xFF40, "3", "`"), + (0xFF41, "M", "a"), + (0xFF42, "M", "b"), + (0xFF43, "M", "c"), + (0xFF44, "M", "d"), + (0xFF45, "M", "e"), + (0xFF46, "M", "f"), + (0xFF47, "M", "g"), + (0xFF48, "M", "h"), + (0xFF49, "M", "i"), + (0xFF4A, "M", "j"), + (0xFF4B, "M", "k"), + (0xFF4C, "M", "l"), + (0xFF4D, "M", "m"), + (0xFF4E, "M", "n"), + (0xFF4F, "M", "o"), + (0xFF50, "M", "p"), + (0xFF51, "M", "q"), + (0xFF52, "M", "r"), + (0xFF53, "M", "s"), + (0xFF54, "M", "t"), + (0xFF55, "M", "u"), + (0xFF56, "M", "v"), + (0xFF57, "M", "w"), + (0xFF58, "M", "x"), + (0xFF59, "M", "y"), + (0xFF5A, "M", "z"), + (0xFF5B, "3", "{"), + (0xFF5C, "3", "|"), + (0xFF5D, "3", "}"), + (0xFF5E, "3", "~"), + (0xFF5F, "M", "⦅"), + (0xFF60, "M", "⦆"), + (0xFF61, "M", "."), + (0xFF62, "M", "「"), + (0xFF63, "M", "」"), + (0xFF64, "M", "、"), + (0xFF65, "M", "・"), + (0xFF66, "M", "ヲ"), + (0xFF67, "M", "ァ"), + (0xFF68, "M", "ィ"), + (0xFF69, "M", "ゥ"), + (0xFF6A, "M", "ェ"), + (0xFF6B, "M", "ォ"), + (0xFF6C, "M", "ャ"), + (0xFF6D, "M", "ュ"), + (0xFF6E, "M", "ョ"), + (0xFF6F, "M", "ッ"), + (0xFF70, "M", "ー"), + (0xFF71, "M", "ア"), + (0xFF72, "M", "イ"), + (0xFF73, "M", "ウ"), + (0xFF74, "M", "エ"), + (0xFF75, "M", "オ"), + (0xFF76, "M", "カ"), + (0xFF77, "M", "キ"), + (0xFF78, "M", "ク"), + (0xFF79, "M", "ケ"), + (0xFF7A, "M", "コ"), + (0xFF7B, "M", "サ"), + (0xFF7C, "M", "シ"), + (0xFF7D, "M", "ス"), + (0xFF7E, "M", "セ"), + (0xFF7F, "M", "ソ"), + (0xFF80, "M", "タ"), + (0xFF81, "M", "チ"), + (0xFF82, "M", "ツ"), + ] + + +def _seg_52() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFF83, "M", "テ"), + (0xFF84, "M", "ト"), + (0xFF85, "M", "ナ"), + (0xFF86, "M", "ニ"), + (0xFF87, "M", "ヌ"), + (0xFF88, "M", "ネ"), + (0xFF89, "M", "ノ"), + (0xFF8A, "M", "ハ"), + (0xFF8B, "M", "ヒ"), + (0xFF8C, "M", "フ"), + (0xFF8D, "M", "ヘ"), + (0xFF8E, "M", "ホ"), + (0xFF8F, "M", "マ"), + (0xFF90, "M", "ミ"), + (0xFF91, "M", "ム"), + (0xFF92, "M", "メ"), + (0xFF93, "M", "モ"), + (0xFF94, "M", "ヤ"), + (0xFF95, "M", "ユ"), + (0xFF96, "M", "ヨ"), + (0xFF97, "M", "ラ"), + (0xFF98, "M", "リ"), + (0xFF99, "M", "ル"), + (0xFF9A, "M", "レ"), + (0xFF9B, "M", "ロ"), + (0xFF9C, "M", "ワ"), + (0xFF9D, "M", "ン"), + (0xFF9E, "M", "゙"), + (0xFF9F, "M", "゚"), + (0xFFA0, "X"), + (0xFFA1, "M", "ᄀ"), + (0xFFA2, "M", "ᄁ"), + (0xFFA3, "M", "ᆪ"), + (0xFFA4, "M", "ᄂ"), + (0xFFA5, "M", "ᆬ"), + (0xFFA6, "M", "ᆭ"), + (0xFFA7, "M", "ᄃ"), + (0xFFA8, "M", "ᄄ"), + (0xFFA9, "M", "ᄅ"), + (0xFFAA, "M", "ᆰ"), + (0xFFAB, "M", "ᆱ"), + (0xFFAC, "M", "ᆲ"), + (0xFFAD, "M", "ᆳ"), + (0xFFAE, "M", "ᆴ"), + (0xFFAF, "M", "ᆵ"), + (0xFFB0, "M", "ᄚ"), + (0xFFB1, "M", "ᄆ"), + (0xFFB2, "M", "ᄇ"), + (0xFFB3, "M", "ᄈ"), + (0xFFB4, "M", "ᄡ"), + (0xFFB5, "M", "ᄉ"), + (0xFFB6, "M", "ᄊ"), + (0xFFB7, "M", "ᄋ"), + (0xFFB8, "M", "ᄌ"), + (0xFFB9, "M", "ᄍ"), + (0xFFBA, "M", "ᄎ"), + (0xFFBB, "M", "ᄏ"), + (0xFFBC, "M", "ᄐ"), + (0xFFBD, "M", "ᄑ"), + (0xFFBE, "M", "ᄒ"), + (0xFFBF, "X"), + (0xFFC2, "M", "ᅡ"), + (0xFFC3, "M", "ᅢ"), + (0xFFC4, "M", "ᅣ"), + (0xFFC5, "M", "ᅤ"), + (0xFFC6, "M", "ᅥ"), + (0xFFC7, "M", "ᅦ"), + (0xFFC8, "X"), + (0xFFCA, "M", "ᅧ"), + (0xFFCB, "M", "ᅨ"), + (0xFFCC, "M", "ᅩ"), + (0xFFCD, "M", "ᅪ"), + (0xFFCE, "M", "ᅫ"), + (0xFFCF, "M", "ᅬ"), + (0xFFD0, "X"), + (0xFFD2, "M", "ᅭ"), + (0xFFD3, "M", "ᅮ"), + (0xFFD4, "M", "ᅯ"), + (0xFFD5, "M", "ᅰ"), + (0xFFD6, "M", "ᅱ"), + (0xFFD7, "M", "ᅲ"), + (0xFFD8, "X"), + (0xFFDA, "M", "ᅳ"), + (0xFFDB, "M", "ᅴ"), + (0xFFDC, "M", "ᅵ"), + (0xFFDD, "X"), + (0xFFE0, "M", "¢"), + (0xFFE1, "M", "£"), + (0xFFE2, "M", "¬"), + (0xFFE3, "3", " ̄"), + (0xFFE4, "M", "¦"), + (0xFFE5, "M", "¥"), + (0xFFE6, "M", "₩"), + (0xFFE7, "X"), + (0xFFE8, "M", "│"), + (0xFFE9, "M", "←"), + (0xFFEA, "M", "↑"), + (0xFFEB, "M", "→"), + (0xFFEC, "M", "↓"), + (0xFFED, "M", "■"), + ] + + +def _seg_53() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0xFFEE, "M", "○"), + (0xFFEF, "X"), + (0x10000, "V"), + (0x1000C, "X"), + (0x1000D, "V"), + (0x10027, "X"), + (0x10028, "V"), + (0x1003B, "X"), + (0x1003C, "V"), + (0x1003E, "X"), + (0x1003F, "V"), + (0x1004E, "X"), + (0x10050, "V"), + (0x1005E, "X"), + (0x10080, "V"), + (0x100FB, "X"), + (0x10100, "V"), + (0x10103, "X"), + (0x10107, "V"), + (0x10134, "X"), + (0x10137, "V"), + (0x1018F, "X"), + (0x10190, "V"), + (0x1019D, "X"), + (0x101A0, "V"), + (0x101A1, "X"), + (0x101D0, "V"), + (0x101FE, "X"), + (0x10280, "V"), + (0x1029D, "X"), + (0x102A0, "V"), + (0x102D1, "X"), + (0x102E0, "V"), + (0x102FC, "X"), + (0x10300, "V"), + (0x10324, "X"), + (0x1032D, "V"), + (0x1034B, "X"), + (0x10350, "V"), + (0x1037B, "X"), + (0x10380, "V"), + (0x1039E, "X"), + (0x1039F, "V"), + (0x103C4, "X"), + (0x103C8, "V"), + (0x103D6, "X"), + (0x10400, "M", "𐐨"), + (0x10401, "M", "𐐩"), + (0x10402, "M", "𐐪"), + (0x10403, "M", "𐐫"), + (0x10404, "M", "𐐬"), + (0x10405, "M", "𐐭"), + (0x10406, "M", "𐐮"), + (0x10407, "M", "𐐯"), + (0x10408, "M", "𐐰"), + (0x10409, "M", "𐐱"), + (0x1040A, "M", "𐐲"), + (0x1040B, "M", "𐐳"), + (0x1040C, "M", "𐐴"), + (0x1040D, "M", "𐐵"), + (0x1040E, "M", "𐐶"), + (0x1040F, "M", "𐐷"), + (0x10410, "M", "𐐸"), + (0x10411, "M", "𐐹"), + (0x10412, "M", "𐐺"), + (0x10413, "M", "𐐻"), + (0x10414, "M", "𐐼"), + (0x10415, "M", "𐐽"), + (0x10416, "M", "𐐾"), + (0x10417, "M", "𐐿"), + (0x10418, "M", "𐑀"), + (0x10419, "M", "𐑁"), + (0x1041A, "M", "𐑂"), + (0x1041B, "M", "𐑃"), + (0x1041C, "M", "𐑄"), + (0x1041D, "M", "𐑅"), + (0x1041E, "M", "𐑆"), + (0x1041F, "M", "𐑇"), + (0x10420, "M", "𐑈"), + (0x10421, "M", "𐑉"), + (0x10422, "M", "𐑊"), + (0x10423, "M", "𐑋"), + (0x10424, "M", "𐑌"), + (0x10425, "M", "𐑍"), + (0x10426, "M", "𐑎"), + (0x10427, "M", "𐑏"), + (0x10428, "V"), + (0x1049E, "X"), + (0x104A0, "V"), + (0x104AA, "X"), + (0x104B0, "M", "𐓘"), + (0x104B1, "M", "𐓙"), + (0x104B2, "M", "𐓚"), + (0x104B3, "M", "𐓛"), + (0x104B4, "M", "𐓜"), + (0x104B5, "M", "𐓝"), + (0x104B6, "M", "𐓞"), + (0x104B7, "M", "𐓟"), + (0x104B8, "M", "𐓠"), + (0x104B9, "M", "𐓡"), + ] + + +def _seg_54() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x104BA, "M", "𐓢"), + (0x104BB, "M", "𐓣"), + (0x104BC, "M", "𐓤"), + (0x104BD, "M", "𐓥"), + (0x104BE, "M", "𐓦"), + (0x104BF, "M", "𐓧"), + (0x104C0, "M", "𐓨"), + (0x104C1, "M", "𐓩"), + (0x104C2, "M", "𐓪"), + (0x104C3, "M", "𐓫"), + (0x104C4, "M", "𐓬"), + (0x104C5, "M", "𐓭"), + (0x104C6, "M", "𐓮"), + (0x104C7, "M", "𐓯"), + (0x104C8, "M", "𐓰"), + (0x104C9, "M", "𐓱"), + (0x104CA, "M", "𐓲"), + (0x104CB, "M", "𐓳"), + (0x104CC, "M", "𐓴"), + (0x104CD, "M", "𐓵"), + (0x104CE, "M", "𐓶"), + (0x104CF, "M", "𐓷"), + (0x104D0, "M", "𐓸"), + (0x104D1, "M", "𐓹"), + (0x104D2, "M", "𐓺"), + (0x104D3, "M", "𐓻"), + (0x104D4, "X"), + (0x104D8, "V"), + (0x104FC, "X"), + (0x10500, "V"), + (0x10528, "X"), + (0x10530, "V"), + (0x10564, "X"), + (0x1056F, "V"), + (0x10570, "M", "𐖗"), + (0x10571, "M", "𐖘"), + (0x10572, "M", "𐖙"), + (0x10573, "M", "𐖚"), + (0x10574, "M", "𐖛"), + (0x10575, "M", "𐖜"), + (0x10576, "M", "𐖝"), + (0x10577, "M", "𐖞"), + (0x10578, "M", "𐖟"), + (0x10579, "M", "𐖠"), + (0x1057A, "M", "𐖡"), + (0x1057B, "X"), + (0x1057C, "M", "𐖣"), + (0x1057D, "M", "𐖤"), + (0x1057E, "M", "𐖥"), + (0x1057F, "M", "𐖦"), + (0x10580, "M", "𐖧"), + (0x10581, "M", "𐖨"), + (0x10582, "M", "𐖩"), + (0x10583, "M", "𐖪"), + (0x10584, "M", "𐖫"), + (0x10585, "M", "𐖬"), + (0x10586, "M", "𐖭"), + (0x10587, "M", "𐖮"), + (0x10588, "M", "𐖯"), + (0x10589, "M", "𐖰"), + (0x1058A, "M", "𐖱"), + (0x1058B, "X"), + (0x1058C, "M", "𐖳"), + (0x1058D, "M", "𐖴"), + (0x1058E, "M", "𐖵"), + (0x1058F, "M", "𐖶"), + (0x10590, "M", "𐖷"), + (0x10591, "M", "𐖸"), + (0x10592, "M", "𐖹"), + (0x10593, "X"), + (0x10594, "M", "𐖻"), + (0x10595, "M", "𐖼"), + (0x10596, "X"), + (0x10597, "V"), + (0x105A2, "X"), + (0x105A3, "V"), + (0x105B2, "X"), + (0x105B3, "V"), + (0x105BA, "X"), + (0x105BB, "V"), + (0x105BD, "X"), + (0x10600, "V"), + (0x10737, "X"), + (0x10740, "V"), + (0x10756, "X"), + (0x10760, "V"), + (0x10768, "X"), + (0x10780, "V"), + (0x10781, "M", "ː"), + (0x10782, "M", "ˑ"), + (0x10783, "M", "æ"), + (0x10784, "M", "ʙ"), + (0x10785, "M", "ɓ"), + (0x10786, "X"), + (0x10787, "M", "ʣ"), + (0x10788, "M", "ꭦ"), + (0x10789, "M", "ʥ"), + (0x1078A, "M", "ʤ"), + (0x1078B, "M", "ɖ"), + (0x1078C, "M", "ɗ"), + ] + + +def _seg_55() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1078D, "M", "ᶑ"), + (0x1078E, "M", "ɘ"), + (0x1078F, "M", "ɞ"), + (0x10790, "M", "ʩ"), + (0x10791, "M", "ɤ"), + (0x10792, "M", "ɢ"), + (0x10793, "M", "ɠ"), + (0x10794, "M", "ʛ"), + (0x10795, "M", "ħ"), + (0x10796, "M", "ʜ"), + (0x10797, "M", "ɧ"), + (0x10798, "M", "ʄ"), + (0x10799, "M", "ʪ"), + (0x1079A, "M", "ʫ"), + (0x1079B, "M", "ɬ"), + (0x1079C, "M", "𝼄"), + (0x1079D, "M", "ꞎ"), + (0x1079E, "M", "ɮ"), + (0x1079F, "M", "𝼅"), + (0x107A0, "M", "ʎ"), + (0x107A1, "M", "𝼆"), + (0x107A2, "M", "ø"), + (0x107A3, "M", "ɶ"), + (0x107A4, "M", "ɷ"), + (0x107A5, "M", "q"), + (0x107A6, "M", "ɺ"), + (0x107A7, "M", "𝼈"), + (0x107A8, "M", "ɽ"), + (0x107A9, "M", "ɾ"), + (0x107AA, "M", "ʀ"), + (0x107AB, "M", "ʨ"), + (0x107AC, "M", "ʦ"), + (0x107AD, "M", "ꭧ"), + (0x107AE, "M", "ʧ"), + (0x107AF, "M", "ʈ"), + (0x107B0, "M", "ⱱ"), + (0x107B1, "X"), + (0x107B2, "M", "ʏ"), + (0x107B3, "M", "ʡ"), + (0x107B4, "M", "ʢ"), + (0x107B5, "M", "ʘ"), + (0x107B6, "M", "ǀ"), + (0x107B7, "M", "ǁ"), + (0x107B8, "M", "ǂ"), + (0x107B9, "M", "𝼊"), + (0x107BA, "M", "𝼞"), + (0x107BB, "X"), + (0x10800, "V"), + (0x10806, "X"), + (0x10808, "V"), + (0x10809, "X"), + (0x1080A, "V"), + (0x10836, "X"), + (0x10837, "V"), + (0x10839, "X"), + (0x1083C, "V"), + (0x1083D, "X"), + (0x1083F, "V"), + (0x10856, "X"), + (0x10857, "V"), + (0x1089F, "X"), + (0x108A7, "V"), + (0x108B0, "X"), + (0x108E0, "V"), + (0x108F3, "X"), + (0x108F4, "V"), + (0x108F6, "X"), + (0x108FB, "V"), + (0x1091C, "X"), + (0x1091F, "V"), + (0x1093A, "X"), + (0x1093F, "V"), + (0x10940, "X"), + (0x10980, "V"), + (0x109B8, "X"), + (0x109BC, "V"), + (0x109D0, "X"), + (0x109D2, "V"), + (0x10A04, "X"), + (0x10A05, "V"), + (0x10A07, "X"), + (0x10A0C, "V"), + (0x10A14, "X"), + (0x10A15, "V"), + (0x10A18, "X"), + (0x10A19, "V"), + (0x10A36, "X"), + (0x10A38, "V"), + (0x10A3B, "X"), + (0x10A3F, "V"), + (0x10A49, "X"), + (0x10A50, "V"), + (0x10A59, "X"), + (0x10A60, "V"), + (0x10AA0, "X"), + (0x10AC0, "V"), + (0x10AE7, "X"), + (0x10AEB, "V"), + (0x10AF7, "X"), + (0x10B00, "V"), + ] + + +def _seg_56() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x10B36, "X"), + (0x10B39, "V"), + (0x10B56, "X"), + (0x10B58, "V"), + (0x10B73, "X"), + (0x10B78, "V"), + (0x10B92, "X"), + (0x10B99, "V"), + (0x10B9D, "X"), + (0x10BA9, "V"), + (0x10BB0, "X"), + (0x10C00, "V"), + (0x10C49, "X"), + (0x10C80, "M", "𐳀"), + (0x10C81, "M", "𐳁"), + (0x10C82, "M", "𐳂"), + (0x10C83, "M", "𐳃"), + (0x10C84, "M", "𐳄"), + (0x10C85, "M", "𐳅"), + (0x10C86, "M", "𐳆"), + (0x10C87, "M", "𐳇"), + (0x10C88, "M", "𐳈"), + (0x10C89, "M", "𐳉"), + (0x10C8A, "M", "𐳊"), + (0x10C8B, "M", "𐳋"), + (0x10C8C, "M", "𐳌"), + (0x10C8D, "M", "𐳍"), + (0x10C8E, "M", "𐳎"), + (0x10C8F, "M", "𐳏"), + (0x10C90, "M", "𐳐"), + (0x10C91, "M", "𐳑"), + (0x10C92, "M", "𐳒"), + (0x10C93, "M", "𐳓"), + (0x10C94, "M", "𐳔"), + (0x10C95, "M", "𐳕"), + (0x10C96, "M", "𐳖"), + (0x10C97, "M", "𐳗"), + (0x10C98, "M", "𐳘"), + (0x10C99, "M", "𐳙"), + (0x10C9A, "M", "𐳚"), + (0x10C9B, "M", "𐳛"), + (0x10C9C, "M", "𐳜"), + (0x10C9D, "M", "𐳝"), + (0x10C9E, "M", "𐳞"), + (0x10C9F, "M", "𐳟"), + (0x10CA0, "M", "𐳠"), + (0x10CA1, "M", "𐳡"), + (0x10CA2, "M", "𐳢"), + (0x10CA3, "M", "𐳣"), + (0x10CA4, "M", "𐳤"), + (0x10CA5, "M", "𐳥"), + (0x10CA6, "M", "𐳦"), + (0x10CA7, "M", "𐳧"), + (0x10CA8, "M", "𐳨"), + (0x10CA9, "M", "𐳩"), + (0x10CAA, "M", "𐳪"), + (0x10CAB, "M", "𐳫"), + (0x10CAC, "M", "𐳬"), + (0x10CAD, "M", "𐳭"), + (0x10CAE, "M", "𐳮"), + (0x10CAF, "M", "𐳯"), + (0x10CB0, "M", "𐳰"), + (0x10CB1, "M", "𐳱"), + (0x10CB2, "M", "𐳲"), + (0x10CB3, "X"), + (0x10CC0, "V"), + (0x10CF3, "X"), + (0x10CFA, "V"), + (0x10D28, "X"), + (0x10D30, "V"), + (0x10D3A, "X"), + (0x10E60, "V"), + (0x10E7F, "X"), + (0x10E80, "V"), + (0x10EAA, "X"), + (0x10EAB, "V"), + (0x10EAE, "X"), + (0x10EB0, "V"), + (0x10EB2, "X"), + (0x10EFD, "V"), + (0x10F28, "X"), + (0x10F30, "V"), + (0x10F5A, "X"), + (0x10F70, "V"), + (0x10F8A, "X"), + (0x10FB0, "V"), + (0x10FCC, "X"), + (0x10FE0, "V"), + (0x10FF7, "X"), + (0x11000, "V"), + (0x1104E, "X"), + (0x11052, "V"), + (0x11076, "X"), + (0x1107F, "V"), + (0x110BD, "X"), + (0x110BE, "V"), + (0x110C3, "X"), + (0x110D0, "V"), + (0x110E9, "X"), + (0x110F0, "V"), + ] + + +def _seg_57() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x110FA, "X"), + (0x11100, "V"), + (0x11135, "X"), + (0x11136, "V"), + (0x11148, "X"), + (0x11150, "V"), + (0x11177, "X"), + (0x11180, "V"), + (0x111E0, "X"), + (0x111E1, "V"), + (0x111F5, "X"), + (0x11200, "V"), + (0x11212, "X"), + (0x11213, "V"), + (0x11242, "X"), + (0x11280, "V"), + (0x11287, "X"), + (0x11288, "V"), + (0x11289, "X"), + (0x1128A, "V"), + (0x1128E, "X"), + (0x1128F, "V"), + (0x1129E, "X"), + (0x1129F, "V"), + (0x112AA, "X"), + (0x112B0, "V"), + (0x112EB, "X"), + (0x112F0, "V"), + (0x112FA, "X"), + (0x11300, "V"), + (0x11304, "X"), + (0x11305, "V"), + (0x1130D, "X"), + (0x1130F, "V"), + (0x11311, "X"), + (0x11313, "V"), + (0x11329, "X"), + (0x1132A, "V"), + (0x11331, "X"), + (0x11332, "V"), + (0x11334, "X"), + (0x11335, "V"), + (0x1133A, "X"), + (0x1133B, "V"), + (0x11345, "X"), + (0x11347, "V"), + (0x11349, "X"), + (0x1134B, "V"), + (0x1134E, "X"), + (0x11350, "V"), + (0x11351, "X"), + (0x11357, "V"), + (0x11358, "X"), + (0x1135D, "V"), + (0x11364, "X"), + (0x11366, "V"), + (0x1136D, "X"), + (0x11370, "V"), + (0x11375, "X"), + (0x11400, "V"), + (0x1145C, "X"), + (0x1145D, "V"), + (0x11462, "X"), + (0x11480, "V"), + (0x114C8, "X"), + (0x114D0, "V"), + (0x114DA, "X"), + (0x11580, "V"), + (0x115B6, "X"), + (0x115B8, "V"), + (0x115DE, "X"), + (0x11600, "V"), + (0x11645, "X"), + (0x11650, "V"), + (0x1165A, "X"), + (0x11660, "V"), + (0x1166D, "X"), + (0x11680, "V"), + (0x116BA, "X"), + (0x116C0, "V"), + (0x116CA, "X"), + (0x11700, "V"), + (0x1171B, "X"), + (0x1171D, "V"), + (0x1172C, "X"), + (0x11730, "V"), + (0x11747, "X"), + (0x11800, "V"), + (0x1183C, "X"), + (0x118A0, "M", "𑣀"), + (0x118A1, "M", "𑣁"), + (0x118A2, "M", "𑣂"), + (0x118A3, "M", "𑣃"), + (0x118A4, "M", "𑣄"), + (0x118A5, "M", "𑣅"), + (0x118A6, "M", "𑣆"), + (0x118A7, "M", "𑣇"), + (0x118A8, "M", "𑣈"), + (0x118A9, "M", "𑣉"), + (0x118AA, "M", "𑣊"), + ] + + +def _seg_58() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x118AB, "M", "𑣋"), + (0x118AC, "M", "𑣌"), + (0x118AD, "M", "𑣍"), + (0x118AE, "M", "𑣎"), + (0x118AF, "M", "𑣏"), + (0x118B0, "M", "𑣐"), + (0x118B1, "M", "𑣑"), + (0x118B2, "M", "𑣒"), + (0x118B3, "M", "𑣓"), + (0x118B4, "M", "𑣔"), + (0x118B5, "M", "𑣕"), + (0x118B6, "M", "𑣖"), + (0x118B7, "M", "𑣗"), + (0x118B8, "M", "𑣘"), + (0x118B9, "M", "𑣙"), + (0x118BA, "M", "𑣚"), + (0x118BB, "M", "𑣛"), + (0x118BC, "M", "𑣜"), + (0x118BD, "M", "𑣝"), + (0x118BE, "M", "𑣞"), + (0x118BF, "M", "𑣟"), + (0x118C0, "V"), + (0x118F3, "X"), + (0x118FF, "V"), + (0x11907, "X"), + (0x11909, "V"), + (0x1190A, "X"), + (0x1190C, "V"), + (0x11914, "X"), + (0x11915, "V"), + (0x11917, "X"), + (0x11918, "V"), + (0x11936, "X"), + (0x11937, "V"), + (0x11939, "X"), + (0x1193B, "V"), + (0x11947, "X"), + (0x11950, "V"), + (0x1195A, "X"), + (0x119A0, "V"), + (0x119A8, "X"), + (0x119AA, "V"), + (0x119D8, "X"), + (0x119DA, "V"), + (0x119E5, "X"), + (0x11A00, "V"), + (0x11A48, "X"), + (0x11A50, "V"), + (0x11AA3, "X"), + (0x11AB0, "V"), + (0x11AF9, "X"), + (0x11B00, "V"), + (0x11B0A, "X"), + (0x11C00, "V"), + (0x11C09, "X"), + (0x11C0A, "V"), + (0x11C37, "X"), + (0x11C38, "V"), + (0x11C46, "X"), + (0x11C50, "V"), + (0x11C6D, "X"), + (0x11C70, "V"), + (0x11C90, "X"), + (0x11C92, "V"), + (0x11CA8, "X"), + (0x11CA9, "V"), + (0x11CB7, "X"), + (0x11D00, "V"), + (0x11D07, "X"), + (0x11D08, "V"), + (0x11D0A, "X"), + (0x11D0B, "V"), + (0x11D37, "X"), + (0x11D3A, "V"), + (0x11D3B, "X"), + (0x11D3C, "V"), + (0x11D3E, "X"), + (0x11D3F, "V"), + (0x11D48, "X"), + (0x11D50, "V"), + (0x11D5A, "X"), + (0x11D60, "V"), + (0x11D66, "X"), + (0x11D67, "V"), + (0x11D69, "X"), + (0x11D6A, "V"), + (0x11D8F, "X"), + (0x11D90, "V"), + (0x11D92, "X"), + (0x11D93, "V"), + (0x11D99, "X"), + (0x11DA0, "V"), + (0x11DAA, "X"), + (0x11EE0, "V"), + (0x11EF9, "X"), + (0x11F00, "V"), + (0x11F11, "X"), + (0x11F12, "V"), + (0x11F3B, "X"), + (0x11F3E, "V"), + ] + + +def _seg_59() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x11F5A, "X"), + (0x11FB0, "V"), + (0x11FB1, "X"), + (0x11FC0, "V"), + (0x11FF2, "X"), + (0x11FFF, "V"), + (0x1239A, "X"), + (0x12400, "V"), + (0x1246F, "X"), + (0x12470, "V"), + (0x12475, "X"), + (0x12480, "V"), + (0x12544, "X"), + (0x12F90, "V"), + (0x12FF3, "X"), + (0x13000, "V"), + (0x13430, "X"), + (0x13440, "V"), + (0x13456, "X"), + (0x14400, "V"), + (0x14647, "X"), + (0x16800, "V"), + (0x16A39, "X"), + (0x16A40, "V"), + (0x16A5F, "X"), + (0x16A60, "V"), + (0x16A6A, "X"), + (0x16A6E, "V"), + (0x16ABF, "X"), + (0x16AC0, "V"), + (0x16ACA, "X"), + (0x16AD0, "V"), + (0x16AEE, "X"), + (0x16AF0, "V"), + (0x16AF6, "X"), + (0x16B00, "V"), + (0x16B46, "X"), + (0x16B50, "V"), + (0x16B5A, "X"), + (0x16B5B, "V"), + (0x16B62, "X"), + (0x16B63, "V"), + (0x16B78, "X"), + (0x16B7D, "V"), + (0x16B90, "X"), + (0x16E40, "M", "𖹠"), + (0x16E41, "M", "𖹡"), + (0x16E42, "M", "𖹢"), + (0x16E43, "M", "𖹣"), + (0x16E44, "M", "𖹤"), + (0x16E45, "M", "𖹥"), + (0x16E46, "M", "𖹦"), + (0x16E47, "M", "𖹧"), + (0x16E48, "M", "𖹨"), + (0x16E49, "M", "𖹩"), + (0x16E4A, "M", "𖹪"), + (0x16E4B, "M", "𖹫"), + (0x16E4C, "M", "𖹬"), + (0x16E4D, "M", "𖹭"), + (0x16E4E, "M", "𖹮"), + (0x16E4F, "M", "𖹯"), + (0x16E50, "M", "𖹰"), + (0x16E51, "M", "𖹱"), + (0x16E52, "M", "𖹲"), + (0x16E53, "M", "𖹳"), + (0x16E54, "M", "𖹴"), + (0x16E55, "M", "𖹵"), + (0x16E56, "M", "𖹶"), + (0x16E57, "M", "𖹷"), + (0x16E58, "M", "𖹸"), + (0x16E59, "M", "𖹹"), + (0x16E5A, "M", "𖹺"), + (0x16E5B, "M", "𖹻"), + (0x16E5C, "M", "𖹼"), + (0x16E5D, "M", "𖹽"), + (0x16E5E, "M", "𖹾"), + (0x16E5F, "M", "𖹿"), + (0x16E60, "V"), + (0x16E9B, "X"), + (0x16F00, "V"), + (0x16F4B, "X"), + (0x16F4F, "V"), + (0x16F88, "X"), + (0x16F8F, "V"), + (0x16FA0, "X"), + (0x16FE0, "V"), + (0x16FE5, "X"), + (0x16FF0, "V"), + (0x16FF2, "X"), + (0x17000, "V"), + (0x187F8, "X"), + (0x18800, "V"), + (0x18CD6, "X"), + (0x18D00, "V"), + (0x18D09, "X"), + (0x1AFF0, "V"), + (0x1AFF4, "X"), + (0x1AFF5, "V"), + (0x1AFFC, "X"), + (0x1AFFD, "V"), + ] + + +def _seg_60() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1AFFF, "X"), + (0x1B000, "V"), + (0x1B123, "X"), + (0x1B132, "V"), + (0x1B133, "X"), + (0x1B150, "V"), + (0x1B153, "X"), + (0x1B155, "V"), + (0x1B156, "X"), + (0x1B164, "V"), + (0x1B168, "X"), + (0x1B170, "V"), + (0x1B2FC, "X"), + (0x1BC00, "V"), + (0x1BC6B, "X"), + (0x1BC70, "V"), + (0x1BC7D, "X"), + (0x1BC80, "V"), + (0x1BC89, "X"), + (0x1BC90, "V"), + (0x1BC9A, "X"), + (0x1BC9C, "V"), + (0x1BCA0, "I"), + (0x1BCA4, "X"), + (0x1CF00, "V"), + (0x1CF2E, "X"), + (0x1CF30, "V"), + (0x1CF47, "X"), + (0x1CF50, "V"), + (0x1CFC4, "X"), + (0x1D000, "V"), + (0x1D0F6, "X"), + (0x1D100, "V"), + (0x1D127, "X"), + (0x1D129, "V"), + (0x1D15E, "M", "𝅗𝅥"), + (0x1D15F, "M", "𝅘𝅥"), + (0x1D160, "M", "𝅘𝅥𝅮"), + (0x1D161, "M", "𝅘𝅥𝅯"), + (0x1D162, "M", "𝅘𝅥𝅰"), + (0x1D163, "M", "𝅘𝅥𝅱"), + (0x1D164, "M", "𝅘𝅥𝅲"), + (0x1D165, "V"), + (0x1D173, "X"), + (0x1D17B, "V"), + (0x1D1BB, "M", "𝆹𝅥"), + (0x1D1BC, "M", "𝆺𝅥"), + (0x1D1BD, "M", "𝆹𝅥𝅮"), + (0x1D1BE, "M", "𝆺𝅥𝅮"), + (0x1D1BF, "M", "𝆹𝅥𝅯"), + (0x1D1C0, "M", "𝆺𝅥𝅯"), + (0x1D1C1, "V"), + (0x1D1EB, "X"), + (0x1D200, "V"), + (0x1D246, "X"), + (0x1D2C0, "V"), + (0x1D2D4, "X"), + (0x1D2E0, "V"), + (0x1D2F4, "X"), + (0x1D300, "V"), + (0x1D357, "X"), + (0x1D360, "V"), + (0x1D379, "X"), + (0x1D400, "M", "a"), + (0x1D401, "M", "b"), + (0x1D402, "M", "c"), + (0x1D403, "M", "d"), + (0x1D404, "M", "e"), + (0x1D405, "M", "f"), + (0x1D406, "M", "g"), + (0x1D407, "M", "h"), + (0x1D408, "M", "i"), + (0x1D409, "M", "j"), + (0x1D40A, "M", "k"), + (0x1D40B, "M", "l"), + (0x1D40C, "M", "m"), + (0x1D40D, "M", "n"), + (0x1D40E, "M", "o"), + (0x1D40F, "M", "p"), + (0x1D410, "M", "q"), + (0x1D411, "M", "r"), + (0x1D412, "M", "s"), + (0x1D413, "M", "t"), + (0x1D414, "M", "u"), + (0x1D415, "M", "v"), + (0x1D416, "M", "w"), + (0x1D417, "M", "x"), + (0x1D418, "M", "y"), + (0x1D419, "M", "z"), + (0x1D41A, "M", "a"), + (0x1D41B, "M", "b"), + (0x1D41C, "M", "c"), + (0x1D41D, "M", "d"), + (0x1D41E, "M", "e"), + (0x1D41F, "M", "f"), + (0x1D420, "M", "g"), + (0x1D421, "M", "h"), + (0x1D422, "M", "i"), + (0x1D423, "M", "j"), + (0x1D424, "M", "k"), + ] + + +def _seg_61() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D425, "M", "l"), + (0x1D426, "M", "m"), + (0x1D427, "M", "n"), + (0x1D428, "M", "o"), + (0x1D429, "M", "p"), + (0x1D42A, "M", "q"), + (0x1D42B, "M", "r"), + (0x1D42C, "M", "s"), + (0x1D42D, "M", "t"), + (0x1D42E, "M", "u"), + (0x1D42F, "M", "v"), + (0x1D430, "M", "w"), + (0x1D431, "M", "x"), + (0x1D432, "M", "y"), + (0x1D433, "M", "z"), + (0x1D434, "M", "a"), + (0x1D435, "M", "b"), + (0x1D436, "M", "c"), + (0x1D437, "M", "d"), + (0x1D438, "M", "e"), + (0x1D439, "M", "f"), + (0x1D43A, "M", "g"), + (0x1D43B, "M", "h"), + (0x1D43C, "M", "i"), + (0x1D43D, "M", "j"), + (0x1D43E, "M", "k"), + (0x1D43F, "M", "l"), + (0x1D440, "M", "m"), + (0x1D441, "M", "n"), + (0x1D442, "M", "o"), + (0x1D443, "M", "p"), + (0x1D444, "M", "q"), + (0x1D445, "M", "r"), + (0x1D446, "M", "s"), + (0x1D447, "M", "t"), + (0x1D448, "M", "u"), + (0x1D449, "M", "v"), + (0x1D44A, "M", "w"), + (0x1D44B, "M", "x"), + (0x1D44C, "M", "y"), + (0x1D44D, "M", "z"), + (0x1D44E, "M", "a"), + (0x1D44F, "M", "b"), + (0x1D450, "M", "c"), + (0x1D451, "M", "d"), + (0x1D452, "M", "e"), + (0x1D453, "M", "f"), + (0x1D454, "M", "g"), + (0x1D455, "X"), + (0x1D456, "M", "i"), + (0x1D457, "M", "j"), + (0x1D458, "M", "k"), + (0x1D459, "M", "l"), + (0x1D45A, "M", "m"), + (0x1D45B, "M", "n"), + (0x1D45C, "M", "o"), + (0x1D45D, "M", "p"), + (0x1D45E, "M", "q"), + (0x1D45F, "M", "r"), + (0x1D460, "M", "s"), + (0x1D461, "M", "t"), + (0x1D462, "M", "u"), + (0x1D463, "M", "v"), + (0x1D464, "M", "w"), + (0x1D465, "M", "x"), + (0x1D466, "M", "y"), + (0x1D467, "M", "z"), + (0x1D468, "M", "a"), + (0x1D469, "M", "b"), + (0x1D46A, "M", "c"), + (0x1D46B, "M", "d"), + (0x1D46C, "M", "e"), + (0x1D46D, "M", "f"), + (0x1D46E, "M", "g"), + (0x1D46F, "M", "h"), + (0x1D470, "M", "i"), + (0x1D471, "M", "j"), + (0x1D472, "M", "k"), + (0x1D473, "M", "l"), + (0x1D474, "M", "m"), + (0x1D475, "M", "n"), + (0x1D476, "M", "o"), + (0x1D477, "M", "p"), + (0x1D478, "M", "q"), + (0x1D479, "M", "r"), + (0x1D47A, "M", "s"), + (0x1D47B, "M", "t"), + (0x1D47C, "M", "u"), + (0x1D47D, "M", "v"), + (0x1D47E, "M", "w"), + (0x1D47F, "M", "x"), + (0x1D480, "M", "y"), + (0x1D481, "M", "z"), + (0x1D482, "M", "a"), + (0x1D483, "M", "b"), + (0x1D484, "M", "c"), + (0x1D485, "M", "d"), + (0x1D486, "M", "e"), + (0x1D487, "M", "f"), + (0x1D488, "M", "g"), + ] + + +def _seg_62() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D489, "M", "h"), + (0x1D48A, "M", "i"), + (0x1D48B, "M", "j"), + (0x1D48C, "M", "k"), + (0x1D48D, "M", "l"), + (0x1D48E, "M", "m"), + (0x1D48F, "M", "n"), + (0x1D490, "M", "o"), + (0x1D491, "M", "p"), + (0x1D492, "M", "q"), + (0x1D493, "M", "r"), + (0x1D494, "M", "s"), + (0x1D495, "M", "t"), + (0x1D496, "M", "u"), + (0x1D497, "M", "v"), + (0x1D498, "M", "w"), + (0x1D499, "M", "x"), + (0x1D49A, "M", "y"), + (0x1D49B, "M", "z"), + (0x1D49C, "M", "a"), + (0x1D49D, "X"), + (0x1D49E, "M", "c"), + (0x1D49F, "M", "d"), + (0x1D4A0, "X"), + (0x1D4A2, "M", "g"), + (0x1D4A3, "X"), + (0x1D4A5, "M", "j"), + (0x1D4A6, "M", "k"), + (0x1D4A7, "X"), + (0x1D4A9, "M", "n"), + (0x1D4AA, "M", "o"), + (0x1D4AB, "M", "p"), + (0x1D4AC, "M", "q"), + (0x1D4AD, "X"), + (0x1D4AE, "M", "s"), + (0x1D4AF, "M", "t"), + (0x1D4B0, "M", "u"), + (0x1D4B1, "M", "v"), + (0x1D4B2, "M", "w"), + (0x1D4B3, "M", "x"), + (0x1D4B4, "M", "y"), + (0x1D4B5, "M", "z"), + (0x1D4B6, "M", "a"), + (0x1D4B7, "M", "b"), + (0x1D4B8, "M", "c"), + (0x1D4B9, "M", "d"), + (0x1D4BA, "X"), + (0x1D4BB, "M", "f"), + (0x1D4BC, "X"), + (0x1D4BD, "M", "h"), + (0x1D4BE, "M", "i"), + (0x1D4BF, "M", "j"), + (0x1D4C0, "M", "k"), + (0x1D4C1, "M", "l"), + (0x1D4C2, "M", "m"), + (0x1D4C3, "M", "n"), + (0x1D4C4, "X"), + (0x1D4C5, "M", "p"), + (0x1D4C6, "M", "q"), + (0x1D4C7, "M", "r"), + (0x1D4C8, "M", "s"), + (0x1D4C9, "M", "t"), + (0x1D4CA, "M", "u"), + (0x1D4CB, "M", "v"), + (0x1D4CC, "M", "w"), + (0x1D4CD, "M", "x"), + (0x1D4CE, "M", "y"), + (0x1D4CF, "M", "z"), + (0x1D4D0, "M", "a"), + (0x1D4D1, "M", "b"), + (0x1D4D2, "M", "c"), + (0x1D4D3, "M", "d"), + (0x1D4D4, "M", "e"), + (0x1D4D5, "M", "f"), + (0x1D4D6, "M", "g"), + (0x1D4D7, "M", "h"), + (0x1D4D8, "M", "i"), + (0x1D4D9, "M", "j"), + (0x1D4DA, "M", "k"), + (0x1D4DB, "M", "l"), + (0x1D4DC, "M", "m"), + (0x1D4DD, "M", "n"), + (0x1D4DE, "M", "o"), + (0x1D4DF, "M", "p"), + (0x1D4E0, "M", "q"), + (0x1D4E1, "M", "r"), + (0x1D4E2, "M", "s"), + (0x1D4E3, "M", "t"), + (0x1D4E4, "M", "u"), + (0x1D4E5, "M", "v"), + (0x1D4E6, "M", "w"), + (0x1D4E7, "M", "x"), + (0x1D4E8, "M", "y"), + (0x1D4E9, "M", "z"), + (0x1D4EA, "M", "a"), + (0x1D4EB, "M", "b"), + (0x1D4EC, "M", "c"), + (0x1D4ED, "M", "d"), + (0x1D4EE, "M", "e"), + (0x1D4EF, "M", "f"), + ] + + +def _seg_63() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D4F0, "M", "g"), + (0x1D4F1, "M", "h"), + (0x1D4F2, "M", "i"), + (0x1D4F3, "M", "j"), + (0x1D4F4, "M", "k"), + (0x1D4F5, "M", "l"), + (0x1D4F6, "M", "m"), + (0x1D4F7, "M", "n"), + (0x1D4F8, "M", "o"), + (0x1D4F9, "M", "p"), + (0x1D4FA, "M", "q"), + (0x1D4FB, "M", "r"), + (0x1D4FC, "M", "s"), + (0x1D4FD, "M", "t"), + (0x1D4FE, "M", "u"), + (0x1D4FF, "M", "v"), + (0x1D500, "M", "w"), + (0x1D501, "M", "x"), + (0x1D502, "M", "y"), + (0x1D503, "M", "z"), + (0x1D504, "M", "a"), + (0x1D505, "M", "b"), + (0x1D506, "X"), + (0x1D507, "M", "d"), + (0x1D508, "M", "e"), + (0x1D509, "M", "f"), + (0x1D50A, "M", "g"), + (0x1D50B, "X"), + (0x1D50D, "M", "j"), + (0x1D50E, "M", "k"), + (0x1D50F, "M", "l"), + (0x1D510, "M", "m"), + (0x1D511, "M", "n"), + (0x1D512, "M", "o"), + (0x1D513, "M", "p"), + (0x1D514, "M", "q"), + (0x1D515, "X"), + (0x1D516, "M", "s"), + (0x1D517, "M", "t"), + (0x1D518, "M", "u"), + (0x1D519, "M", "v"), + (0x1D51A, "M", "w"), + (0x1D51B, "M", "x"), + (0x1D51C, "M", "y"), + (0x1D51D, "X"), + (0x1D51E, "M", "a"), + (0x1D51F, "M", "b"), + (0x1D520, "M", "c"), + (0x1D521, "M", "d"), + (0x1D522, "M", "e"), + (0x1D523, "M", "f"), + (0x1D524, "M", "g"), + (0x1D525, "M", "h"), + (0x1D526, "M", "i"), + (0x1D527, "M", "j"), + (0x1D528, "M", "k"), + (0x1D529, "M", "l"), + (0x1D52A, "M", "m"), + (0x1D52B, "M", "n"), + (0x1D52C, "M", "o"), + (0x1D52D, "M", "p"), + (0x1D52E, "M", "q"), + (0x1D52F, "M", "r"), + (0x1D530, "M", "s"), + (0x1D531, "M", "t"), + (0x1D532, "M", "u"), + (0x1D533, "M", "v"), + (0x1D534, "M", "w"), + (0x1D535, "M", "x"), + (0x1D536, "M", "y"), + (0x1D537, "M", "z"), + (0x1D538, "M", "a"), + (0x1D539, "M", "b"), + (0x1D53A, "X"), + (0x1D53B, "M", "d"), + (0x1D53C, "M", "e"), + (0x1D53D, "M", "f"), + (0x1D53E, "M", "g"), + (0x1D53F, "X"), + (0x1D540, "M", "i"), + (0x1D541, "M", "j"), + (0x1D542, "M", "k"), + (0x1D543, "M", "l"), + (0x1D544, "M", "m"), + (0x1D545, "X"), + (0x1D546, "M", "o"), + (0x1D547, "X"), + (0x1D54A, "M", "s"), + (0x1D54B, "M", "t"), + (0x1D54C, "M", "u"), + (0x1D54D, "M", "v"), + (0x1D54E, "M", "w"), + (0x1D54F, "M", "x"), + (0x1D550, "M", "y"), + (0x1D551, "X"), + (0x1D552, "M", "a"), + (0x1D553, "M", "b"), + (0x1D554, "M", "c"), + (0x1D555, "M", "d"), + (0x1D556, "M", "e"), + ] + + +def _seg_64() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D557, "M", "f"), + (0x1D558, "M", "g"), + (0x1D559, "M", "h"), + (0x1D55A, "M", "i"), + (0x1D55B, "M", "j"), + (0x1D55C, "M", "k"), + (0x1D55D, "M", "l"), + (0x1D55E, "M", "m"), + (0x1D55F, "M", "n"), + (0x1D560, "M", "o"), + (0x1D561, "M", "p"), + (0x1D562, "M", "q"), + (0x1D563, "M", "r"), + (0x1D564, "M", "s"), + (0x1D565, "M", "t"), + (0x1D566, "M", "u"), + (0x1D567, "M", "v"), + (0x1D568, "M", "w"), + (0x1D569, "M", "x"), + (0x1D56A, "M", "y"), + (0x1D56B, "M", "z"), + (0x1D56C, "M", "a"), + (0x1D56D, "M", "b"), + (0x1D56E, "M", "c"), + (0x1D56F, "M", "d"), + (0x1D570, "M", "e"), + (0x1D571, "M", "f"), + (0x1D572, "M", "g"), + (0x1D573, "M", "h"), + (0x1D574, "M", "i"), + (0x1D575, "M", "j"), + (0x1D576, "M", "k"), + (0x1D577, "M", "l"), + (0x1D578, "M", "m"), + (0x1D579, "M", "n"), + (0x1D57A, "M", "o"), + (0x1D57B, "M", "p"), + (0x1D57C, "M", "q"), + (0x1D57D, "M", "r"), + (0x1D57E, "M", "s"), + (0x1D57F, "M", "t"), + (0x1D580, "M", "u"), + (0x1D581, "M", "v"), + (0x1D582, "M", "w"), + (0x1D583, "M", "x"), + (0x1D584, "M", "y"), + (0x1D585, "M", "z"), + (0x1D586, "M", "a"), + (0x1D587, "M", "b"), + (0x1D588, "M", "c"), + (0x1D589, "M", "d"), + (0x1D58A, "M", "e"), + (0x1D58B, "M", "f"), + (0x1D58C, "M", "g"), + (0x1D58D, "M", "h"), + (0x1D58E, "M", "i"), + (0x1D58F, "M", "j"), + (0x1D590, "M", "k"), + (0x1D591, "M", "l"), + (0x1D592, "M", "m"), + (0x1D593, "M", "n"), + (0x1D594, "M", "o"), + (0x1D595, "M", "p"), + (0x1D596, "M", "q"), + (0x1D597, "M", "r"), + (0x1D598, "M", "s"), + (0x1D599, "M", "t"), + (0x1D59A, "M", "u"), + (0x1D59B, "M", "v"), + (0x1D59C, "M", "w"), + (0x1D59D, "M", "x"), + (0x1D59E, "M", "y"), + (0x1D59F, "M", "z"), + (0x1D5A0, "M", "a"), + (0x1D5A1, "M", "b"), + (0x1D5A2, "M", "c"), + (0x1D5A3, "M", "d"), + (0x1D5A4, "M", "e"), + (0x1D5A5, "M", "f"), + (0x1D5A6, "M", "g"), + (0x1D5A7, "M", "h"), + (0x1D5A8, "M", "i"), + (0x1D5A9, "M", "j"), + (0x1D5AA, "M", "k"), + (0x1D5AB, "M", "l"), + (0x1D5AC, "M", "m"), + (0x1D5AD, "M", "n"), + (0x1D5AE, "M", "o"), + (0x1D5AF, "M", "p"), + (0x1D5B0, "M", "q"), + (0x1D5B1, "M", "r"), + (0x1D5B2, "M", "s"), + (0x1D5B3, "M", "t"), + (0x1D5B4, "M", "u"), + (0x1D5B5, "M", "v"), + (0x1D5B6, "M", "w"), + (0x1D5B7, "M", "x"), + (0x1D5B8, "M", "y"), + (0x1D5B9, "M", "z"), + (0x1D5BA, "M", "a"), + ] + + +def _seg_65() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D5BB, "M", "b"), + (0x1D5BC, "M", "c"), + (0x1D5BD, "M", "d"), + (0x1D5BE, "M", "e"), + (0x1D5BF, "M", "f"), + (0x1D5C0, "M", "g"), + (0x1D5C1, "M", "h"), + (0x1D5C2, "M", "i"), + (0x1D5C3, "M", "j"), + (0x1D5C4, "M", "k"), + (0x1D5C5, "M", "l"), + (0x1D5C6, "M", "m"), + (0x1D5C7, "M", "n"), + (0x1D5C8, "M", "o"), + (0x1D5C9, "M", "p"), + (0x1D5CA, "M", "q"), + (0x1D5CB, "M", "r"), + (0x1D5CC, "M", "s"), + (0x1D5CD, "M", "t"), + (0x1D5CE, "M", "u"), + (0x1D5CF, "M", "v"), + (0x1D5D0, "M", "w"), + (0x1D5D1, "M", "x"), + (0x1D5D2, "M", "y"), + (0x1D5D3, "M", "z"), + (0x1D5D4, "M", "a"), + (0x1D5D5, "M", "b"), + (0x1D5D6, "M", "c"), + (0x1D5D7, "M", "d"), + (0x1D5D8, "M", "e"), + (0x1D5D9, "M", "f"), + (0x1D5DA, "M", "g"), + (0x1D5DB, "M", "h"), + (0x1D5DC, "M", "i"), + (0x1D5DD, "M", "j"), + (0x1D5DE, "M", "k"), + (0x1D5DF, "M", "l"), + (0x1D5E0, "M", "m"), + (0x1D5E1, "M", "n"), + (0x1D5E2, "M", "o"), + (0x1D5E3, "M", "p"), + (0x1D5E4, "M", "q"), + (0x1D5E5, "M", "r"), + (0x1D5E6, "M", "s"), + (0x1D5E7, "M", "t"), + (0x1D5E8, "M", "u"), + (0x1D5E9, "M", "v"), + (0x1D5EA, "M", "w"), + (0x1D5EB, "M", "x"), + (0x1D5EC, "M", "y"), + (0x1D5ED, "M", "z"), + (0x1D5EE, "M", "a"), + (0x1D5EF, "M", "b"), + (0x1D5F0, "M", "c"), + (0x1D5F1, "M", "d"), + (0x1D5F2, "M", "e"), + (0x1D5F3, "M", "f"), + (0x1D5F4, "M", "g"), + (0x1D5F5, "M", "h"), + (0x1D5F6, "M", "i"), + (0x1D5F7, "M", "j"), + (0x1D5F8, "M", "k"), + (0x1D5F9, "M", "l"), + (0x1D5FA, "M", "m"), + (0x1D5FB, "M", "n"), + (0x1D5FC, "M", "o"), + (0x1D5FD, "M", "p"), + (0x1D5FE, "M", "q"), + (0x1D5FF, "M", "r"), + (0x1D600, "M", "s"), + (0x1D601, "M", "t"), + (0x1D602, "M", "u"), + (0x1D603, "M", "v"), + (0x1D604, "M", "w"), + (0x1D605, "M", "x"), + (0x1D606, "M", "y"), + (0x1D607, "M", "z"), + (0x1D608, "M", "a"), + (0x1D609, "M", "b"), + (0x1D60A, "M", "c"), + (0x1D60B, "M", "d"), + (0x1D60C, "M", "e"), + (0x1D60D, "M", "f"), + (0x1D60E, "M", "g"), + (0x1D60F, "M", "h"), + (0x1D610, "M", "i"), + (0x1D611, "M", "j"), + (0x1D612, "M", "k"), + (0x1D613, "M", "l"), + (0x1D614, "M", "m"), + (0x1D615, "M", "n"), + (0x1D616, "M", "o"), + (0x1D617, "M", "p"), + (0x1D618, "M", "q"), + (0x1D619, "M", "r"), + (0x1D61A, "M", "s"), + (0x1D61B, "M", "t"), + (0x1D61C, "M", "u"), + (0x1D61D, "M", "v"), + (0x1D61E, "M", "w"), + ] + + +def _seg_66() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D61F, "M", "x"), + (0x1D620, "M", "y"), + (0x1D621, "M", "z"), + (0x1D622, "M", "a"), + (0x1D623, "M", "b"), + (0x1D624, "M", "c"), + (0x1D625, "M", "d"), + (0x1D626, "M", "e"), + (0x1D627, "M", "f"), + (0x1D628, "M", "g"), + (0x1D629, "M", "h"), + (0x1D62A, "M", "i"), + (0x1D62B, "M", "j"), + (0x1D62C, "M", "k"), + (0x1D62D, "M", "l"), + (0x1D62E, "M", "m"), + (0x1D62F, "M", "n"), + (0x1D630, "M", "o"), + (0x1D631, "M", "p"), + (0x1D632, "M", "q"), + (0x1D633, "M", "r"), + (0x1D634, "M", "s"), + (0x1D635, "M", "t"), + (0x1D636, "M", "u"), + (0x1D637, "M", "v"), + (0x1D638, "M", "w"), + (0x1D639, "M", "x"), + (0x1D63A, "M", "y"), + (0x1D63B, "M", "z"), + (0x1D63C, "M", "a"), + (0x1D63D, "M", "b"), + (0x1D63E, "M", "c"), + (0x1D63F, "M", "d"), + (0x1D640, "M", "e"), + (0x1D641, "M", "f"), + (0x1D642, "M", "g"), + (0x1D643, "M", "h"), + (0x1D644, "M", "i"), + (0x1D645, "M", "j"), + (0x1D646, "M", "k"), + (0x1D647, "M", "l"), + (0x1D648, "M", "m"), + (0x1D649, "M", "n"), + (0x1D64A, "M", "o"), + (0x1D64B, "M", "p"), + (0x1D64C, "M", "q"), + (0x1D64D, "M", "r"), + (0x1D64E, "M", "s"), + (0x1D64F, "M", "t"), + (0x1D650, "M", "u"), + (0x1D651, "M", "v"), + (0x1D652, "M", "w"), + (0x1D653, "M", "x"), + (0x1D654, "M", "y"), + (0x1D655, "M", "z"), + (0x1D656, "M", "a"), + (0x1D657, "M", "b"), + (0x1D658, "M", "c"), + (0x1D659, "M", "d"), + (0x1D65A, "M", "e"), + (0x1D65B, "M", "f"), + (0x1D65C, "M", "g"), + (0x1D65D, "M", "h"), + (0x1D65E, "M", "i"), + (0x1D65F, "M", "j"), + (0x1D660, "M", "k"), + (0x1D661, "M", "l"), + (0x1D662, "M", "m"), + (0x1D663, "M", "n"), + (0x1D664, "M", "o"), + (0x1D665, "M", "p"), + (0x1D666, "M", "q"), + (0x1D667, "M", "r"), + (0x1D668, "M", "s"), + (0x1D669, "M", "t"), + (0x1D66A, "M", "u"), + (0x1D66B, "M", "v"), + (0x1D66C, "M", "w"), + (0x1D66D, "M", "x"), + (0x1D66E, "M", "y"), + (0x1D66F, "M", "z"), + (0x1D670, "M", "a"), + (0x1D671, "M", "b"), + (0x1D672, "M", "c"), + (0x1D673, "M", "d"), + (0x1D674, "M", "e"), + (0x1D675, "M", "f"), + (0x1D676, "M", "g"), + (0x1D677, "M", "h"), + (0x1D678, "M", "i"), + (0x1D679, "M", "j"), + (0x1D67A, "M", "k"), + (0x1D67B, "M", "l"), + (0x1D67C, "M", "m"), + (0x1D67D, "M", "n"), + (0x1D67E, "M", "o"), + (0x1D67F, "M", "p"), + (0x1D680, "M", "q"), + (0x1D681, "M", "r"), + (0x1D682, "M", "s"), + ] + + +def _seg_67() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D683, "M", "t"), + (0x1D684, "M", "u"), + (0x1D685, "M", "v"), + (0x1D686, "M", "w"), + (0x1D687, "M", "x"), + (0x1D688, "M", "y"), + (0x1D689, "M", "z"), + (0x1D68A, "M", "a"), + (0x1D68B, "M", "b"), + (0x1D68C, "M", "c"), + (0x1D68D, "M", "d"), + (0x1D68E, "M", "e"), + (0x1D68F, "M", "f"), + (0x1D690, "M", "g"), + (0x1D691, "M", "h"), + (0x1D692, "M", "i"), + (0x1D693, "M", "j"), + (0x1D694, "M", "k"), + (0x1D695, "M", "l"), + (0x1D696, "M", "m"), + (0x1D697, "M", "n"), + (0x1D698, "M", "o"), + (0x1D699, "M", "p"), + (0x1D69A, "M", "q"), + (0x1D69B, "M", "r"), + (0x1D69C, "M", "s"), + (0x1D69D, "M", "t"), + (0x1D69E, "M", "u"), + (0x1D69F, "M", "v"), + (0x1D6A0, "M", "w"), + (0x1D6A1, "M", "x"), + (0x1D6A2, "M", "y"), + (0x1D6A3, "M", "z"), + (0x1D6A4, "M", "ı"), + (0x1D6A5, "M", "ȷ"), + (0x1D6A6, "X"), + (0x1D6A8, "M", "α"), + (0x1D6A9, "M", "β"), + (0x1D6AA, "M", "γ"), + (0x1D6AB, "M", "δ"), + (0x1D6AC, "M", "ε"), + (0x1D6AD, "M", "ζ"), + (0x1D6AE, "M", "η"), + (0x1D6AF, "M", "θ"), + (0x1D6B0, "M", "ι"), + (0x1D6B1, "M", "κ"), + (0x1D6B2, "M", "λ"), + (0x1D6B3, "M", "μ"), + (0x1D6B4, "M", "ν"), + (0x1D6B5, "M", "ξ"), + (0x1D6B6, "M", "ο"), + (0x1D6B7, "M", "π"), + (0x1D6B8, "M", "ρ"), + (0x1D6B9, "M", "θ"), + (0x1D6BA, "M", "σ"), + (0x1D6BB, "M", "τ"), + (0x1D6BC, "M", "υ"), + (0x1D6BD, "M", "φ"), + (0x1D6BE, "M", "χ"), + (0x1D6BF, "M", "ψ"), + (0x1D6C0, "M", "ω"), + (0x1D6C1, "M", "∇"), + (0x1D6C2, "M", "α"), + (0x1D6C3, "M", "β"), + (0x1D6C4, "M", "γ"), + (0x1D6C5, "M", "δ"), + (0x1D6C6, "M", "ε"), + (0x1D6C7, "M", "ζ"), + (0x1D6C8, "M", "η"), + (0x1D6C9, "M", "θ"), + (0x1D6CA, "M", "ι"), + (0x1D6CB, "M", "κ"), + (0x1D6CC, "M", "λ"), + (0x1D6CD, "M", "μ"), + (0x1D6CE, "M", "ν"), + (0x1D6CF, "M", "ξ"), + (0x1D6D0, "M", "ο"), + (0x1D6D1, "M", "π"), + (0x1D6D2, "M", "ρ"), + (0x1D6D3, "M", "σ"), + (0x1D6D5, "M", "τ"), + (0x1D6D6, "M", "υ"), + (0x1D6D7, "M", "φ"), + (0x1D6D8, "M", "χ"), + (0x1D6D9, "M", "ψ"), + (0x1D6DA, "M", "ω"), + (0x1D6DB, "M", "∂"), + (0x1D6DC, "M", "ε"), + (0x1D6DD, "M", "θ"), + (0x1D6DE, "M", "κ"), + (0x1D6DF, "M", "φ"), + (0x1D6E0, "M", "ρ"), + (0x1D6E1, "M", "π"), + (0x1D6E2, "M", "α"), + (0x1D6E3, "M", "β"), + (0x1D6E4, "M", "γ"), + (0x1D6E5, "M", "δ"), + (0x1D6E6, "M", "ε"), + (0x1D6E7, "M", "ζ"), + (0x1D6E8, "M", "η"), + ] + + +def _seg_68() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D6E9, "M", "θ"), + (0x1D6EA, "M", "ι"), + (0x1D6EB, "M", "κ"), + (0x1D6EC, "M", "λ"), + (0x1D6ED, "M", "μ"), + (0x1D6EE, "M", "ν"), + (0x1D6EF, "M", "ξ"), + (0x1D6F0, "M", "ο"), + (0x1D6F1, "M", "π"), + (0x1D6F2, "M", "ρ"), + (0x1D6F3, "M", "θ"), + (0x1D6F4, "M", "σ"), + (0x1D6F5, "M", "τ"), + (0x1D6F6, "M", "υ"), + (0x1D6F7, "M", "φ"), + (0x1D6F8, "M", "χ"), + (0x1D6F9, "M", "ψ"), + (0x1D6FA, "M", "ω"), + (0x1D6FB, "M", "∇"), + (0x1D6FC, "M", "α"), + (0x1D6FD, "M", "β"), + (0x1D6FE, "M", "γ"), + (0x1D6FF, "M", "δ"), + (0x1D700, "M", "ε"), + (0x1D701, "M", "ζ"), + (0x1D702, "M", "η"), + (0x1D703, "M", "θ"), + (0x1D704, "M", "ι"), + (0x1D705, "M", "κ"), + (0x1D706, "M", "λ"), + (0x1D707, "M", "μ"), + (0x1D708, "M", "ν"), + (0x1D709, "M", "ξ"), + (0x1D70A, "M", "ο"), + (0x1D70B, "M", "π"), + (0x1D70C, "M", "ρ"), + (0x1D70D, "M", "σ"), + (0x1D70F, "M", "τ"), + (0x1D710, "M", "υ"), + (0x1D711, "M", "φ"), + (0x1D712, "M", "χ"), + (0x1D713, "M", "ψ"), + (0x1D714, "M", "ω"), + (0x1D715, "M", "∂"), + (0x1D716, "M", "ε"), + (0x1D717, "M", "θ"), + (0x1D718, "M", "κ"), + (0x1D719, "M", "φ"), + (0x1D71A, "M", "ρ"), + (0x1D71B, "M", "π"), + (0x1D71C, "M", "α"), + (0x1D71D, "M", "β"), + (0x1D71E, "M", "γ"), + (0x1D71F, "M", "δ"), + (0x1D720, "M", "ε"), + (0x1D721, "M", "ζ"), + (0x1D722, "M", "η"), + (0x1D723, "M", "θ"), + (0x1D724, "M", "ι"), + (0x1D725, "M", "κ"), + (0x1D726, "M", "λ"), + (0x1D727, "M", "μ"), + (0x1D728, "M", "ν"), + (0x1D729, "M", "ξ"), + (0x1D72A, "M", "ο"), + (0x1D72B, "M", "π"), + (0x1D72C, "M", "ρ"), + (0x1D72D, "M", "θ"), + (0x1D72E, "M", "σ"), + (0x1D72F, "M", "τ"), + (0x1D730, "M", "υ"), + (0x1D731, "M", "φ"), + (0x1D732, "M", "χ"), + (0x1D733, "M", "ψ"), + (0x1D734, "M", "ω"), + (0x1D735, "M", "∇"), + (0x1D736, "M", "α"), + (0x1D737, "M", "β"), + (0x1D738, "M", "γ"), + (0x1D739, "M", "δ"), + (0x1D73A, "M", "ε"), + (0x1D73B, "M", "ζ"), + (0x1D73C, "M", "η"), + (0x1D73D, "M", "θ"), + (0x1D73E, "M", "ι"), + (0x1D73F, "M", "κ"), + (0x1D740, "M", "λ"), + (0x1D741, "M", "μ"), + (0x1D742, "M", "ν"), + (0x1D743, "M", "ξ"), + (0x1D744, "M", "ο"), + (0x1D745, "M", "π"), + (0x1D746, "M", "ρ"), + (0x1D747, "M", "σ"), + (0x1D749, "M", "τ"), + (0x1D74A, "M", "υ"), + (0x1D74B, "M", "φ"), + (0x1D74C, "M", "χ"), + (0x1D74D, "M", "ψ"), + (0x1D74E, "M", "ω"), + ] + + +def _seg_69() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D74F, "M", "∂"), + (0x1D750, "M", "ε"), + (0x1D751, "M", "θ"), + (0x1D752, "M", "κ"), + (0x1D753, "M", "φ"), + (0x1D754, "M", "ρ"), + (0x1D755, "M", "π"), + (0x1D756, "M", "α"), + (0x1D757, "M", "β"), + (0x1D758, "M", "γ"), + (0x1D759, "M", "δ"), + (0x1D75A, "M", "ε"), + (0x1D75B, "M", "ζ"), + (0x1D75C, "M", "η"), + (0x1D75D, "M", "θ"), + (0x1D75E, "M", "ι"), + (0x1D75F, "M", "κ"), + (0x1D760, "M", "λ"), + (0x1D761, "M", "μ"), + (0x1D762, "M", "ν"), + (0x1D763, "M", "ξ"), + (0x1D764, "M", "ο"), + (0x1D765, "M", "π"), + (0x1D766, "M", "ρ"), + (0x1D767, "M", "θ"), + (0x1D768, "M", "σ"), + (0x1D769, "M", "τ"), + (0x1D76A, "M", "υ"), + (0x1D76B, "M", "φ"), + (0x1D76C, "M", "χ"), + (0x1D76D, "M", "ψ"), + (0x1D76E, "M", "ω"), + (0x1D76F, "M", "∇"), + (0x1D770, "M", "α"), + (0x1D771, "M", "β"), + (0x1D772, "M", "γ"), + (0x1D773, "M", "δ"), + (0x1D774, "M", "ε"), + (0x1D775, "M", "ζ"), + (0x1D776, "M", "η"), + (0x1D777, "M", "θ"), + (0x1D778, "M", "ι"), + (0x1D779, "M", "κ"), + (0x1D77A, "M", "λ"), + (0x1D77B, "M", "μ"), + (0x1D77C, "M", "ν"), + (0x1D77D, "M", "ξ"), + (0x1D77E, "M", "ο"), + (0x1D77F, "M", "π"), + (0x1D780, "M", "ρ"), + (0x1D781, "M", "σ"), + (0x1D783, "M", "τ"), + (0x1D784, "M", "υ"), + (0x1D785, "M", "φ"), + (0x1D786, "M", "χ"), + (0x1D787, "M", "ψ"), + (0x1D788, "M", "ω"), + (0x1D789, "M", "∂"), + (0x1D78A, "M", "ε"), + (0x1D78B, "M", "θ"), + (0x1D78C, "M", "κ"), + (0x1D78D, "M", "φ"), + (0x1D78E, "M", "ρ"), + (0x1D78F, "M", "π"), + (0x1D790, "M", "α"), + (0x1D791, "M", "β"), + (0x1D792, "M", "γ"), + (0x1D793, "M", "δ"), + (0x1D794, "M", "ε"), + (0x1D795, "M", "ζ"), + (0x1D796, "M", "η"), + (0x1D797, "M", "θ"), + (0x1D798, "M", "ι"), + (0x1D799, "M", "κ"), + (0x1D79A, "M", "λ"), + (0x1D79B, "M", "μ"), + (0x1D79C, "M", "ν"), + (0x1D79D, "M", "ξ"), + (0x1D79E, "M", "ο"), + (0x1D79F, "M", "π"), + (0x1D7A0, "M", "ρ"), + (0x1D7A1, "M", "θ"), + (0x1D7A2, "M", "σ"), + (0x1D7A3, "M", "τ"), + (0x1D7A4, "M", "υ"), + (0x1D7A5, "M", "φ"), + (0x1D7A6, "M", "χ"), + (0x1D7A7, "M", "ψ"), + (0x1D7A8, "M", "ω"), + (0x1D7A9, "M", "∇"), + (0x1D7AA, "M", "α"), + (0x1D7AB, "M", "β"), + (0x1D7AC, "M", "γ"), + (0x1D7AD, "M", "δ"), + (0x1D7AE, "M", "ε"), + (0x1D7AF, "M", "ζ"), + (0x1D7B0, "M", "η"), + (0x1D7B1, "M", "θ"), + (0x1D7B2, "M", "ι"), + (0x1D7B3, "M", "κ"), + ] + + +def _seg_70() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1D7B4, "M", "λ"), + (0x1D7B5, "M", "μ"), + (0x1D7B6, "M", "ν"), + (0x1D7B7, "M", "ξ"), + (0x1D7B8, "M", "ο"), + (0x1D7B9, "M", "π"), + (0x1D7BA, "M", "ρ"), + (0x1D7BB, "M", "σ"), + (0x1D7BD, "M", "τ"), + (0x1D7BE, "M", "υ"), + (0x1D7BF, "M", "φ"), + (0x1D7C0, "M", "χ"), + (0x1D7C1, "M", "ψ"), + (0x1D7C2, "M", "ω"), + (0x1D7C3, "M", "∂"), + (0x1D7C4, "M", "ε"), + (0x1D7C5, "M", "θ"), + (0x1D7C6, "M", "κ"), + (0x1D7C7, "M", "φ"), + (0x1D7C8, "M", "ρ"), + (0x1D7C9, "M", "π"), + (0x1D7CA, "M", "ϝ"), + (0x1D7CC, "X"), + (0x1D7CE, "M", "0"), + (0x1D7CF, "M", "1"), + (0x1D7D0, "M", "2"), + (0x1D7D1, "M", "3"), + (0x1D7D2, "M", "4"), + (0x1D7D3, "M", "5"), + (0x1D7D4, "M", "6"), + (0x1D7D5, "M", "7"), + (0x1D7D6, "M", "8"), + (0x1D7D7, "M", "9"), + (0x1D7D8, "M", "0"), + (0x1D7D9, "M", "1"), + (0x1D7DA, "M", "2"), + (0x1D7DB, "M", "3"), + (0x1D7DC, "M", "4"), + (0x1D7DD, "M", "5"), + (0x1D7DE, "M", "6"), + (0x1D7DF, "M", "7"), + (0x1D7E0, "M", "8"), + (0x1D7E1, "M", "9"), + (0x1D7E2, "M", "0"), + (0x1D7E3, "M", "1"), + (0x1D7E4, "M", "2"), + (0x1D7E5, "M", "3"), + (0x1D7E6, "M", "4"), + (0x1D7E7, "M", "5"), + (0x1D7E8, "M", "6"), + (0x1D7E9, "M", "7"), + (0x1D7EA, "M", "8"), + (0x1D7EB, "M", "9"), + (0x1D7EC, "M", "0"), + (0x1D7ED, "M", "1"), + (0x1D7EE, "M", "2"), + (0x1D7EF, "M", "3"), + (0x1D7F0, "M", "4"), + (0x1D7F1, "M", "5"), + (0x1D7F2, "M", "6"), + (0x1D7F3, "M", "7"), + (0x1D7F4, "M", "8"), + (0x1D7F5, "M", "9"), + (0x1D7F6, "M", "0"), + (0x1D7F7, "M", "1"), + (0x1D7F8, "M", "2"), + (0x1D7F9, "M", "3"), + (0x1D7FA, "M", "4"), + (0x1D7FB, "M", "5"), + (0x1D7FC, "M", "6"), + (0x1D7FD, "M", "7"), + (0x1D7FE, "M", "8"), + (0x1D7FF, "M", "9"), + (0x1D800, "V"), + (0x1DA8C, "X"), + (0x1DA9B, "V"), + (0x1DAA0, "X"), + (0x1DAA1, "V"), + (0x1DAB0, "X"), + (0x1DF00, "V"), + (0x1DF1F, "X"), + (0x1DF25, "V"), + (0x1DF2B, "X"), + (0x1E000, "V"), + (0x1E007, "X"), + (0x1E008, "V"), + (0x1E019, "X"), + (0x1E01B, "V"), + (0x1E022, "X"), + (0x1E023, "V"), + (0x1E025, "X"), + (0x1E026, "V"), + (0x1E02B, "X"), + (0x1E030, "M", "а"), + (0x1E031, "M", "б"), + (0x1E032, "M", "в"), + (0x1E033, "M", "г"), + (0x1E034, "M", "д"), + (0x1E035, "M", "е"), + (0x1E036, "M", "ж"), + ] + + +def _seg_71() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E037, "M", "з"), + (0x1E038, "M", "и"), + (0x1E039, "M", "к"), + (0x1E03A, "M", "л"), + (0x1E03B, "M", "м"), + (0x1E03C, "M", "о"), + (0x1E03D, "M", "п"), + (0x1E03E, "M", "р"), + (0x1E03F, "M", "с"), + (0x1E040, "M", "т"), + (0x1E041, "M", "у"), + (0x1E042, "M", "ф"), + (0x1E043, "M", "х"), + (0x1E044, "M", "ц"), + (0x1E045, "M", "ч"), + (0x1E046, "M", "ш"), + (0x1E047, "M", "ы"), + (0x1E048, "M", "э"), + (0x1E049, "M", "ю"), + (0x1E04A, "M", "ꚉ"), + (0x1E04B, "M", "ә"), + (0x1E04C, "M", "і"), + (0x1E04D, "M", "ј"), + (0x1E04E, "M", "ө"), + (0x1E04F, "M", "ү"), + (0x1E050, "M", "ӏ"), + (0x1E051, "M", "а"), + (0x1E052, "M", "б"), + (0x1E053, "M", "в"), + (0x1E054, "M", "г"), + (0x1E055, "M", "д"), + (0x1E056, "M", "е"), + (0x1E057, "M", "ж"), + (0x1E058, "M", "з"), + (0x1E059, "M", "и"), + (0x1E05A, "M", "к"), + (0x1E05B, "M", "л"), + (0x1E05C, "M", "о"), + (0x1E05D, "M", "п"), + (0x1E05E, "M", "с"), + (0x1E05F, "M", "у"), + (0x1E060, "M", "ф"), + (0x1E061, "M", "х"), + (0x1E062, "M", "ц"), + (0x1E063, "M", "ч"), + (0x1E064, "M", "ш"), + (0x1E065, "M", "ъ"), + (0x1E066, "M", "ы"), + (0x1E067, "M", "ґ"), + (0x1E068, "M", "і"), + (0x1E069, "M", "ѕ"), + (0x1E06A, "M", "џ"), + (0x1E06B, "M", "ҫ"), + (0x1E06C, "M", "ꙑ"), + (0x1E06D, "M", "ұ"), + (0x1E06E, "X"), + (0x1E08F, "V"), + (0x1E090, "X"), + (0x1E100, "V"), + (0x1E12D, "X"), + (0x1E130, "V"), + (0x1E13E, "X"), + (0x1E140, "V"), + (0x1E14A, "X"), + (0x1E14E, "V"), + (0x1E150, "X"), + (0x1E290, "V"), + (0x1E2AF, "X"), + (0x1E2C0, "V"), + (0x1E2FA, "X"), + (0x1E2FF, "V"), + (0x1E300, "X"), + (0x1E4D0, "V"), + (0x1E4FA, "X"), + (0x1E7E0, "V"), + (0x1E7E7, "X"), + (0x1E7E8, "V"), + (0x1E7EC, "X"), + (0x1E7ED, "V"), + (0x1E7EF, "X"), + (0x1E7F0, "V"), + (0x1E7FF, "X"), + (0x1E800, "V"), + (0x1E8C5, "X"), + (0x1E8C7, "V"), + (0x1E8D7, "X"), + (0x1E900, "M", "𞤢"), + (0x1E901, "M", "𞤣"), + (0x1E902, "M", "𞤤"), + (0x1E903, "M", "𞤥"), + (0x1E904, "M", "𞤦"), + (0x1E905, "M", "𞤧"), + (0x1E906, "M", "𞤨"), + (0x1E907, "M", "𞤩"), + (0x1E908, "M", "𞤪"), + (0x1E909, "M", "𞤫"), + (0x1E90A, "M", "𞤬"), + (0x1E90B, "M", "𞤭"), + (0x1E90C, "M", "𞤮"), + (0x1E90D, "M", "𞤯"), + ] + + +def _seg_72() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1E90E, "M", "𞤰"), + (0x1E90F, "M", "𞤱"), + (0x1E910, "M", "𞤲"), + (0x1E911, "M", "𞤳"), + (0x1E912, "M", "𞤴"), + (0x1E913, "M", "𞤵"), + (0x1E914, "M", "𞤶"), + (0x1E915, "M", "𞤷"), + (0x1E916, "M", "𞤸"), + (0x1E917, "M", "𞤹"), + (0x1E918, "M", "𞤺"), + (0x1E919, "M", "𞤻"), + (0x1E91A, "M", "𞤼"), + (0x1E91B, "M", "𞤽"), + (0x1E91C, "M", "𞤾"), + (0x1E91D, "M", "𞤿"), + (0x1E91E, "M", "𞥀"), + (0x1E91F, "M", "𞥁"), + (0x1E920, "M", "𞥂"), + (0x1E921, "M", "𞥃"), + (0x1E922, "V"), + (0x1E94C, "X"), + (0x1E950, "V"), + (0x1E95A, "X"), + (0x1E95E, "V"), + (0x1E960, "X"), + (0x1EC71, "V"), + (0x1ECB5, "X"), + (0x1ED01, "V"), + (0x1ED3E, "X"), + (0x1EE00, "M", "ا"), + (0x1EE01, "M", "ب"), + (0x1EE02, "M", "ج"), + (0x1EE03, "M", "د"), + (0x1EE04, "X"), + (0x1EE05, "M", "و"), + (0x1EE06, "M", "ز"), + (0x1EE07, "M", "ح"), + (0x1EE08, "M", "ط"), + (0x1EE09, "M", "ي"), + (0x1EE0A, "M", "ك"), + (0x1EE0B, "M", "ل"), + (0x1EE0C, "M", "م"), + (0x1EE0D, "M", "ن"), + (0x1EE0E, "M", "س"), + (0x1EE0F, "M", "ع"), + (0x1EE10, "M", "ف"), + (0x1EE11, "M", "ص"), + (0x1EE12, "M", "ق"), + (0x1EE13, "M", "ر"), + (0x1EE14, "M", "ش"), + (0x1EE15, "M", "ت"), + (0x1EE16, "M", "ث"), + (0x1EE17, "M", "خ"), + (0x1EE18, "M", "ذ"), + (0x1EE19, "M", "ض"), + (0x1EE1A, "M", "ظ"), + (0x1EE1B, "M", "غ"), + (0x1EE1C, "M", "ٮ"), + (0x1EE1D, "M", "ں"), + (0x1EE1E, "M", "ڡ"), + (0x1EE1F, "M", "ٯ"), + (0x1EE20, "X"), + (0x1EE21, "M", "ب"), + (0x1EE22, "M", "ج"), + (0x1EE23, "X"), + (0x1EE24, "M", "ه"), + (0x1EE25, "X"), + (0x1EE27, "M", "ح"), + (0x1EE28, "X"), + (0x1EE29, "M", "ي"), + (0x1EE2A, "M", "ك"), + (0x1EE2B, "M", "ل"), + (0x1EE2C, "M", "م"), + (0x1EE2D, "M", "ن"), + (0x1EE2E, "M", "س"), + (0x1EE2F, "M", "ع"), + (0x1EE30, "M", "ف"), + (0x1EE31, "M", "ص"), + (0x1EE32, "M", "ق"), + (0x1EE33, "X"), + (0x1EE34, "M", "ش"), + (0x1EE35, "M", "ت"), + (0x1EE36, "M", "ث"), + (0x1EE37, "M", "خ"), + (0x1EE38, "X"), + (0x1EE39, "M", "ض"), + (0x1EE3A, "X"), + (0x1EE3B, "M", "غ"), + (0x1EE3C, "X"), + (0x1EE42, "M", "ج"), + (0x1EE43, "X"), + (0x1EE47, "M", "ح"), + (0x1EE48, "X"), + (0x1EE49, "M", "ي"), + (0x1EE4A, "X"), + (0x1EE4B, "M", "ل"), + (0x1EE4C, "X"), + (0x1EE4D, "M", "ن"), + (0x1EE4E, "M", "س"), + ] + + +def _seg_73() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EE4F, "M", "ع"), + (0x1EE50, "X"), + (0x1EE51, "M", "ص"), + (0x1EE52, "M", "ق"), + (0x1EE53, "X"), + (0x1EE54, "M", "ش"), + (0x1EE55, "X"), + (0x1EE57, "M", "خ"), + (0x1EE58, "X"), + (0x1EE59, "M", "ض"), + (0x1EE5A, "X"), + (0x1EE5B, "M", "غ"), + (0x1EE5C, "X"), + (0x1EE5D, "M", "ں"), + (0x1EE5E, "X"), + (0x1EE5F, "M", "ٯ"), + (0x1EE60, "X"), + (0x1EE61, "M", "ب"), + (0x1EE62, "M", "ج"), + (0x1EE63, "X"), + (0x1EE64, "M", "ه"), + (0x1EE65, "X"), + (0x1EE67, "M", "ح"), + (0x1EE68, "M", "ط"), + (0x1EE69, "M", "ي"), + (0x1EE6A, "M", "ك"), + (0x1EE6B, "X"), + (0x1EE6C, "M", "م"), + (0x1EE6D, "M", "ن"), + (0x1EE6E, "M", "س"), + (0x1EE6F, "M", "ع"), + (0x1EE70, "M", "ف"), + (0x1EE71, "M", "ص"), + (0x1EE72, "M", "ق"), + (0x1EE73, "X"), + (0x1EE74, "M", "ش"), + (0x1EE75, "M", "ت"), + (0x1EE76, "M", "ث"), + (0x1EE77, "M", "خ"), + (0x1EE78, "X"), + (0x1EE79, "M", "ض"), + (0x1EE7A, "M", "ظ"), + (0x1EE7B, "M", "غ"), + (0x1EE7C, "M", "ٮ"), + (0x1EE7D, "X"), + (0x1EE7E, "M", "ڡ"), + (0x1EE7F, "X"), + (0x1EE80, "M", "ا"), + (0x1EE81, "M", "ب"), + (0x1EE82, "M", "ج"), + (0x1EE83, "M", "د"), + (0x1EE84, "M", "ه"), + (0x1EE85, "M", "و"), + (0x1EE86, "M", "ز"), + (0x1EE87, "M", "ح"), + (0x1EE88, "M", "ط"), + (0x1EE89, "M", "ي"), + (0x1EE8A, "X"), + (0x1EE8B, "M", "ل"), + (0x1EE8C, "M", "م"), + (0x1EE8D, "M", "ن"), + (0x1EE8E, "M", "س"), + (0x1EE8F, "M", "ع"), + (0x1EE90, "M", "ف"), + (0x1EE91, "M", "ص"), + (0x1EE92, "M", "ق"), + (0x1EE93, "M", "ر"), + (0x1EE94, "M", "ش"), + (0x1EE95, "M", "ت"), + (0x1EE96, "M", "ث"), + (0x1EE97, "M", "خ"), + (0x1EE98, "M", "ذ"), + (0x1EE99, "M", "ض"), + (0x1EE9A, "M", "ظ"), + (0x1EE9B, "M", "غ"), + (0x1EE9C, "X"), + (0x1EEA1, "M", "ب"), + (0x1EEA2, "M", "ج"), + (0x1EEA3, "M", "د"), + (0x1EEA4, "X"), + (0x1EEA5, "M", "و"), + (0x1EEA6, "M", "ز"), + (0x1EEA7, "M", "ح"), + (0x1EEA8, "M", "ط"), + (0x1EEA9, "M", "ي"), + (0x1EEAA, "X"), + (0x1EEAB, "M", "ل"), + (0x1EEAC, "M", "م"), + (0x1EEAD, "M", "ن"), + (0x1EEAE, "M", "س"), + (0x1EEAF, "M", "ع"), + (0x1EEB0, "M", "ف"), + (0x1EEB1, "M", "ص"), + (0x1EEB2, "M", "ق"), + (0x1EEB3, "M", "ر"), + (0x1EEB4, "M", "ش"), + (0x1EEB5, "M", "ت"), + (0x1EEB6, "M", "ث"), + (0x1EEB7, "M", "خ"), + (0x1EEB8, "M", "ذ"), + ] + + +def _seg_74() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1EEB9, "M", "ض"), + (0x1EEBA, "M", "ظ"), + (0x1EEBB, "M", "غ"), + (0x1EEBC, "X"), + (0x1EEF0, "V"), + (0x1EEF2, "X"), + (0x1F000, "V"), + (0x1F02C, "X"), + (0x1F030, "V"), + (0x1F094, "X"), + (0x1F0A0, "V"), + (0x1F0AF, "X"), + (0x1F0B1, "V"), + (0x1F0C0, "X"), + (0x1F0C1, "V"), + (0x1F0D0, "X"), + (0x1F0D1, "V"), + (0x1F0F6, "X"), + (0x1F101, "3", "0,"), + (0x1F102, "3", "1,"), + (0x1F103, "3", "2,"), + (0x1F104, "3", "3,"), + (0x1F105, "3", "4,"), + (0x1F106, "3", "5,"), + (0x1F107, "3", "6,"), + (0x1F108, "3", "7,"), + (0x1F109, "3", "8,"), + (0x1F10A, "3", "9,"), + (0x1F10B, "V"), + (0x1F110, "3", "(a)"), + (0x1F111, "3", "(b)"), + (0x1F112, "3", "(c)"), + (0x1F113, "3", "(d)"), + (0x1F114, "3", "(e)"), + (0x1F115, "3", "(f)"), + (0x1F116, "3", "(g)"), + (0x1F117, "3", "(h)"), + (0x1F118, "3", "(i)"), + (0x1F119, "3", "(j)"), + (0x1F11A, "3", "(k)"), + (0x1F11B, "3", "(l)"), + (0x1F11C, "3", "(m)"), + (0x1F11D, "3", "(n)"), + (0x1F11E, "3", "(o)"), + (0x1F11F, "3", "(p)"), + (0x1F120, "3", "(q)"), + (0x1F121, "3", "(r)"), + (0x1F122, "3", "(s)"), + (0x1F123, "3", "(t)"), + (0x1F124, "3", "(u)"), + (0x1F125, "3", "(v)"), + (0x1F126, "3", "(w)"), + (0x1F127, "3", "(x)"), + (0x1F128, "3", "(y)"), + (0x1F129, "3", "(z)"), + (0x1F12A, "M", "〔s〕"), + (0x1F12B, "M", "c"), + (0x1F12C, "M", "r"), + (0x1F12D, "M", "cd"), + (0x1F12E, "M", "wz"), + (0x1F12F, "V"), + (0x1F130, "M", "a"), + (0x1F131, "M", "b"), + (0x1F132, "M", "c"), + (0x1F133, "M", "d"), + (0x1F134, "M", "e"), + (0x1F135, "M", "f"), + (0x1F136, "M", "g"), + (0x1F137, "M", "h"), + (0x1F138, "M", "i"), + (0x1F139, "M", "j"), + (0x1F13A, "M", "k"), + (0x1F13B, "M", "l"), + (0x1F13C, "M", "m"), + (0x1F13D, "M", "n"), + (0x1F13E, "M", "o"), + (0x1F13F, "M", "p"), + (0x1F140, "M", "q"), + (0x1F141, "M", "r"), + (0x1F142, "M", "s"), + (0x1F143, "M", "t"), + (0x1F144, "M", "u"), + (0x1F145, "M", "v"), + (0x1F146, "M", "w"), + (0x1F147, "M", "x"), + (0x1F148, "M", "y"), + (0x1F149, "M", "z"), + (0x1F14A, "M", "hv"), + (0x1F14B, "M", "mv"), + (0x1F14C, "M", "sd"), + (0x1F14D, "M", "ss"), + (0x1F14E, "M", "ppv"), + (0x1F14F, "M", "wc"), + (0x1F150, "V"), + (0x1F16A, "M", "mc"), + (0x1F16B, "M", "md"), + (0x1F16C, "M", "mr"), + (0x1F16D, "V"), + (0x1F190, "M", "dj"), + (0x1F191, "V"), + ] + + +def _seg_75() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1F1AE, "X"), + (0x1F1E6, "V"), + (0x1F200, "M", "ほか"), + (0x1F201, "M", "ココ"), + (0x1F202, "M", "サ"), + (0x1F203, "X"), + (0x1F210, "M", "手"), + (0x1F211, "M", "字"), + (0x1F212, "M", "双"), + (0x1F213, "M", "デ"), + (0x1F214, "M", "二"), + (0x1F215, "M", "多"), + (0x1F216, "M", "解"), + (0x1F217, "M", "天"), + (0x1F218, "M", "交"), + (0x1F219, "M", "映"), + (0x1F21A, "M", "無"), + (0x1F21B, "M", "料"), + (0x1F21C, "M", "前"), + (0x1F21D, "M", "後"), + (0x1F21E, "M", "再"), + (0x1F21F, "M", "新"), + (0x1F220, "M", "初"), + (0x1F221, "M", "終"), + (0x1F222, "M", "生"), + (0x1F223, "M", "販"), + (0x1F224, "M", "声"), + (0x1F225, "M", "吹"), + (0x1F226, "M", "演"), + (0x1F227, "M", "投"), + (0x1F228, "M", "捕"), + (0x1F229, "M", "一"), + (0x1F22A, "M", "三"), + (0x1F22B, "M", "遊"), + (0x1F22C, "M", "左"), + (0x1F22D, "M", "中"), + (0x1F22E, "M", "右"), + (0x1F22F, "M", "指"), + (0x1F230, "M", "走"), + (0x1F231, "M", "打"), + (0x1F232, "M", "禁"), + (0x1F233, "M", "空"), + (0x1F234, "M", "合"), + (0x1F235, "M", "満"), + (0x1F236, "M", "有"), + (0x1F237, "M", "月"), + (0x1F238, "M", "申"), + (0x1F239, "M", "割"), + (0x1F23A, "M", "営"), + (0x1F23B, "M", "配"), + (0x1F23C, "X"), + (0x1F240, "M", "〔本〕"), + (0x1F241, "M", "〔三〕"), + (0x1F242, "M", "〔二〕"), + (0x1F243, "M", "〔安〕"), + (0x1F244, "M", "〔点〕"), + (0x1F245, "M", "〔打〕"), + (0x1F246, "M", "〔盗〕"), + (0x1F247, "M", "〔勝〕"), + (0x1F248, "M", "〔敗〕"), + (0x1F249, "X"), + (0x1F250, "M", "得"), + (0x1F251, "M", "可"), + (0x1F252, "X"), + (0x1F260, "V"), + (0x1F266, "X"), + (0x1F300, "V"), + (0x1F6D8, "X"), + (0x1F6DC, "V"), + (0x1F6ED, "X"), + (0x1F6F0, "V"), + (0x1F6FD, "X"), + (0x1F700, "V"), + (0x1F777, "X"), + (0x1F77B, "V"), + (0x1F7DA, "X"), + (0x1F7E0, "V"), + (0x1F7EC, "X"), + (0x1F7F0, "V"), + (0x1F7F1, "X"), + (0x1F800, "V"), + (0x1F80C, "X"), + (0x1F810, "V"), + (0x1F848, "X"), + (0x1F850, "V"), + (0x1F85A, "X"), + (0x1F860, "V"), + (0x1F888, "X"), + (0x1F890, "V"), + (0x1F8AE, "X"), + (0x1F8B0, "V"), + (0x1F8B2, "X"), + (0x1F900, "V"), + (0x1FA54, "X"), + (0x1FA60, "V"), + (0x1FA6E, "X"), + (0x1FA70, "V"), + (0x1FA7D, "X"), + (0x1FA80, "V"), + (0x1FA89, "X"), + ] + + +def _seg_76() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x1FA90, "V"), + (0x1FABE, "X"), + (0x1FABF, "V"), + (0x1FAC6, "X"), + (0x1FACE, "V"), + (0x1FADC, "X"), + (0x1FAE0, "V"), + (0x1FAE9, "X"), + (0x1FAF0, "V"), + (0x1FAF9, "X"), + (0x1FB00, "V"), + (0x1FB93, "X"), + (0x1FB94, "V"), + (0x1FBCB, "X"), + (0x1FBF0, "M", "0"), + (0x1FBF1, "M", "1"), + (0x1FBF2, "M", "2"), + (0x1FBF3, "M", "3"), + (0x1FBF4, "M", "4"), + (0x1FBF5, "M", "5"), + (0x1FBF6, "M", "6"), + (0x1FBF7, "M", "7"), + (0x1FBF8, "M", "8"), + (0x1FBF9, "M", "9"), + (0x1FBFA, "X"), + (0x20000, "V"), + (0x2A6E0, "X"), + (0x2A700, "V"), + (0x2B73A, "X"), + (0x2B740, "V"), + (0x2B81E, "X"), + (0x2B820, "V"), + (0x2CEA2, "X"), + (0x2CEB0, "V"), + (0x2EBE1, "X"), + (0x2EBF0, "V"), + (0x2EE5E, "X"), + (0x2F800, "M", "丽"), + (0x2F801, "M", "丸"), + (0x2F802, "M", "乁"), + (0x2F803, "M", "𠄢"), + (0x2F804, "M", "你"), + (0x2F805, "M", "侮"), + (0x2F806, "M", "侻"), + (0x2F807, "M", "倂"), + (0x2F808, "M", "偺"), + (0x2F809, "M", "備"), + (0x2F80A, "M", "僧"), + (0x2F80B, "M", "像"), + (0x2F80C, "M", "㒞"), + (0x2F80D, "M", "𠘺"), + (0x2F80E, "M", "免"), + (0x2F80F, "M", "兔"), + (0x2F810, "M", "兤"), + (0x2F811, "M", "具"), + (0x2F812, "M", "𠔜"), + (0x2F813, "M", "㒹"), + (0x2F814, "M", "內"), + (0x2F815, "M", "再"), + (0x2F816, "M", "𠕋"), + (0x2F817, "M", "冗"), + (0x2F818, "M", "冤"), + (0x2F819, "M", "仌"), + (0x2F81A, "M", "冬"), + (0x2F81B, "M", "况"), + (0x2F81C, "M", "𩇟"), + (0x2F81D, "M", "凵"), + (0x2F81E, "M", "刃"), + (0x2F81F, "M", "㓟"), + (0x2F820, "M", "刻"), + (0x2F821, "M", "剆"), + (0x2F822, "M", "割"), + (0x2F823, "M", "剷"), + (0x2F824, "M", "㔕"), + (0x2F825, "M", "勇"), + (0x2F826, "M", "勉"), + (0x2F827, "M", "勤"), + (0x2F828, "M", "勺"), + (0x2F829, "M", "包"), + (0x2F82A, "M", "匆"), + (0x2F82B, "M", "北"), + (0x2F82C, "M", "卉"), + (0x2F82D, "M", "卑"), + (0x2F82E, "M", "博"), + (0x2F82F, "M", "即"), + (0x2F830, "M", "卽"), + (0x2F831, "M", "卿"), + (0x2F834, "M", "𠨬"), + (0x2F835, "M", "灰"), + (0x2F836, "M", "及"), + (0x2F837, "M", "叟"), + (0x2F838, "M", "𠭣"), + (0x2F839, "M", "叫"), + (0x2F83A, "M", "叱"), + (0x2F83B, "M", "吆"), + (0x2F83C, "M", "咞"), + (0x2F83D, "M", "吸"), + (0x2F83E, "M", "呈"), + (0x2F83F, "M", "周"), + (0x2F840, "M", "咢"), + ] + + +def _seg_77() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F841, "M", "哶"), + (0x2F842, "M", "唐"), + (0x2F843, "M", "啓"), + (0x2F844, "M", "啣"), + (0x2F845, "M", "善"), + (0x2F847, "M", "喙"), + (0x2F848, "M", "喫"), + (0x2F849, "M", "喳"), + (0x2F84A, "M", "嗂"), + (0x2F84B, "M", "圖"), + (0x2F84C, "M", "嘆"), + (0x2F84D, "M", "圗"), + (0x2F84E, "M", "噑"), + (0x2F84F, "M", "噴"), + (0x2F850, "M", "切"), + (0x2F851, "M", "壮"), + (0x2F852, "M", "城"), + (0x2F853, "M", "埴"), + (0x2F854, "M", "堍"), + (0x2F855, "M", "型"), + (0x2F856, "M", "堲"), + (0x2F857, "M", "報"), + (0x2F858, "M", "墬"), + (0x2F859, "M", "𡓤"), + (0x2F85A, "M", "売"), + (0x2F85B, "M", "壷"), + (0x2F85C, "M", "夆"), + (0x2F85D, "M", "多"), + (0x2F85E, "M", "夢"), + (0x2F85F, "M", "奢"), + (0x2F860, "M", "𡚨"), + (0x2F861, "M", "𡛪"), + (0x2F862, "M", "姬"), + (0x2F863, "M", "娛"), + (0x2F864, "M", "娧"), + (0x2F865, "M", "姘"), + (0x2F866, "M", "婦"), + (0x2F867, "M", "㛮"), + (0x2F868, "X"), + (0x2F869, "M", "嬈"), + (0x2F86A, "M", "嬾"), + (0x2F86C, "M", "𡧈"), + (0x2F86D, "M", "寃"), + (0x2F86E, "M", "寘"), + (0x2F86F, "M", "寧"), + (0x2F870, "M", "寳"), + (0x2F871, "M", "𡬘"), + (0x2F872, "M", "寿"), + (0x2F873, "M", "将"), + (0x2F874, "X"), + (0x2F875, "M", "尢"), + (0x2F876, "M", "㞁"), + (0x2F877, "M", "屠"), + (0x2F878, "M", "屮"), + (0x2F879, "M", "峀"), + (0x2F87A, "M", "岍"), + (0x2F87B, "M", "𡷤"), + (0x2F87C, "M", "嵃"), + (0x2F87D, "M", "𡷦"), + (0x2F87E, "M", "嵮"), + (0x2F87F, "M", "嵫"), + (0x2F880, "M", "嵼"), + (0x2F881, "M", "巡"), + (0x2F882, "M", "巢"), + (0x2F883, "M", "㠯"), + (0x2F884, "M", "巽"), + (0x2F885, "M", "帨"), + (0x2F886, "M", "帽"), + (0x2F887, "M", "幩"), + (0x2F888, "M", "㡢"), + (0x2F889, "M", "𢆃"), + (0x2F88A, "M", "㡼"), + (0x2F88B, "M", "庰"), + (0x2F88C, "M", "庳"), + (0x2F88D, "M", "庶"), + (0x2F88E, "M", "廊"), + (0x2F88F, "M", "𪎒"), + (0x2F890, "M", "廾"), + (0x2F891, "M", "𢌱"), + (0x2F893, "M", "舁"), + (0x2F894, "M", "弢"), + (0x2F896, "M", "㣇"), + (0x2F897, "M", "𣊸"), + (0x2F898, "M", "𦇚"), + (0x2F899, "M", "形"), + (0x2F89A, "M", "彫"), + (0x2F89B, "M", "㣣"), + (0x2F89C, "M", "徚"), + (0x2F89D, "M", "忍"), + (0x2F89E, "M", "志"), + (0x2F89F, "M", "忹"), + (0x2F8A0, "M", "悁"), + (0x2F8A1, "M", "㤺"), + (0x2F8A2, "M", "㤜"), + (0x2F8A3, "M", "悔"), + (0x2F8A4, "M", "𢛔"), + (0x2F8A5, "M", "惇"), + (0x2F8A6, "M", "慈"), + (0x2F8A7, "M", "慌"), + (0x2F8A8, "M", "慎"), + ] + + +def _seg_78() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F8A9, "M", "慌"), + (0x2F8AA, "M", "慺"), + (0x2F8AB, "M", "憎"), + (0x2F8AC, "M", "憲"), + (0x2F8AD, "M", "憤"), + (0x2F8AE, "M", "憯"), + (0x2F8AF, "M", "懞"), + (0x2F8B0, "M", "懲"), + (0x2F8B1, "M", "懶"), + (0x2F8B2, "M", "成"), + (0x2F8B3, "M", "戛"), + (0x2F8B4, "M", "扝"), + (0x2F8B5, "M", "抱"), + (0x2F8B6, "M", "拔"), + (0x2F8B7, "M", "捐"), + (0x2F8B8, "M", "𢬌"), + (0x2F8B9, "M", "挽"), + (0x2F8BA, "M", "拼"), + (0x2F8BB, "M", "捨"), + (0x2F8BC, "M", "掃"), + (0x2F8BD, "M", "揤"), + (0x2F8BE, "M", "𢯱"), + (0x2F8BF, "M", "搢"), + (0x2F8C0, "M", "揅"), + (0x2F8C1, "M", "掩"), + (0x2F8C2, "M", "㨮"), + (0x2F8C3, "M", "摩"), + (0x2F8C4, "M", "摾"), + (0x2F8C5, "M", "撝"), + (0x2F8C6, "M", "摷"), + (0x2F8C7, "M", "㩬"), + (0x2F8C8, "M", "敏"), + (0x2F8C9, "M", "敬"), + (0x2F8CA, "M", "𣀊"), + (0x2F8CB, "M", "旣"), + (0x2F8CC, "M", "書"), + (0x2F8CD, "M", "晉"), + (0x2F8CE, "M", "㬙"), + (0x2F8CF, "M", "暑"), + (0x2F8D0, "M", "㬈"), + (0x2F8D1, "M", "㫤"), + (0x2F8D2, "M", "冒"), + (0x2F8D3, "M", "冕"), + (0x2F8D4, "M", "最"), + (0x2F8D5, "M", "暜"), + (0x2F8D6, "M", "肭"), + (0x2F8D7, "M", "䏙"), + (0x2F8D8, "M", "朗"), + (0x2F8D9, "M", "望"), + (0x2F8DA, "M", "朡"), + (0x2F8DB, "M", "杞"), + (0x2F8DC, "M", "杓"), + (0x2F8DD, "M", "𣏃"), + (0x2F8DE, "M", "㭉"), + (0x2F8DF, "M", "柺"), + (0x2F8E0, "M", "枅"), + (0x2F8E1, "M", "桒"), + (0x2F8E2, "M", "梅"), + (0x2F8E3, "M", "𣑭"), + (0x2F8E4, "M", "梎"), + (0x2F8E5, "M", "栟"), + (0x2F8E6, "M", "椔"), + (0x2F8E7, "M", "㮝"), + (0x2F8E8, "M", "楂"), + (0x2F8E9, "M", "榣"), + (0x2F8EA, "M", "槪"), + (0x2F8EB, "M", "檨"), + (0x2F8EC, "M", "𣚣"), + (0x2F8ED, "M", "櫛"), + (0x2F8EE, "M", "㰘"), + (0x2F8EF, "M", "次"), + (0x2F8F0, "M", "𣢧"), + (0x2F8F1, "M", "歔"), + (0x2F8F2, "M", "㱎"), + (0x2F8F3, "M", "歲"), + (0x2F8F4, "M", "殟"), + (0x2F8F5, "M", "殺"), + (0x2F8F6, "M", "殻"), + (0x2F8F7, "M", "𣪍"), + (0x2F8F8, "M", "𡴋"), + (0x2F8F9, "M", "𣫺"), + (0x2F8FA, "M", "汎"), + (0x2F8FB, "M", "𣲼"), + (0x2F8FC, "M", "沿"), + (0x2F8FD, "M", "泍"), + (0x2F8FE, "M", "汧"), + (0x2F8FF, "M", "洖"), + (0x2F900, "M", "派"), + (0x2F901, "M", "海"), + (0x2F902, "M", "流"), + (0x2F903, "M", "浩"), + (0x2F904, "M", "浸"), + (0x2F905, "M", "涅"), + (0x2F906, "M", "𣴞"), + (0x2F907, "M", "洴"), + (0x2F908, "M", "港"), + (0x2F909, "M", "湮"), + (0x2F90A, "M", "㴳"), + (0x2F90B, "M", "滋"), + (0x2F90C, "M", "滇"), + ] + + +def _seg_79() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F90D, "M", "𣻑"), + (0x2F90E, "M", "淹"), + (0x2F90F, "M", "潮"), + (0x2F910, "M", "𣽞"), + (0x2F911, "M", "𣾎"), + (0x2F912, "M", "濆"), + (0x2F913, "M", "瀹"), + (0x2F914, "M", "瀞"), + (0x2F915, "M", "瀛"), + (0x2F916, "M", "㶖"), + (0x2F917, "M", "灊"), + (0x2F918, "M", "災"), + (0x2F919, "M", "灷"), + (0x2F91A, "M", "炭"), + (0x2F91B, "M", "𠔥"), + (0x2F91C, "M", "煅"), + (0x2F91D, "M", "𤉣"), + (0x2F91E, "M", "熜"), + (0x2F91F, "X"), + (0x2F920, "M", "爨"), + (0x2F921, "M", "爵"), + (0x2F922, "M", "牐"), + (0x2F923, "M", "𤘈"), + (0x2F924, "M", "犀"), + (0x2F925, "M", "犕"), + (0x2F926, "M", "𤜵"), + (0x2F927, "M", "𤠔"), + (0x2F928, "M", "獺"), + (0x2F929, "M", "王"), + (0x2F92A, "M", "㺬"), + (0x2F92B, "M", "玥"), + (0x2F92C, "M", "㺸"), + (0x2F92E, "M", "瑇"), + (0x2F92F, "M", "瑜"), + (0x2F930, "M", "瑱"), + (0x2F931, "M", "璅"), + (0x2F932, "M", "瓊"), + (0x2F933, "M", "㼛"), + (0x2F934, "M", "甤"), + (0x2F935, "M", "𤰶"), + (0x2F936, "M", "甾"), + (0x2F937, "M", "𤲒"), + (0x2F938, "M", "異"), + (0x2F939, "M", "𢆟"), + (0x2F93A, "M", "瘐"), + (0x2F93B, "M", "𤾡"), + (0x2F93C, "M", "𤾸"), + (0x2F93D, "M", "𥁄"), + (0x2F93E, "M", "㿼"), + (0x2F93F, "M", "䀈"), + (0x2F940, "M", "直"), + (0x2F941, "M", "𥃳"), + (0x2F942, "M", "𥃲"), + (0x2F943, "M", "𥄙"), + (0x2F944, "M", "𥄳"), + (0x2F945, "M", "眞"), + (0x2F946, "M", "真"), + (0x2F948, "M", "睊"), + (0x2F949, "M", "䀹"), + (0x2F94A, "M", "瞋"), + (0x2F94B, "M", "䁆"), + (0x2F94C, "M", "䂖"), + (0x2F94D, "M", "𥐝"), + (0x2F94E, "M", "硎"), + (0x2F94F, "M", "碌"), + (0x2F950, "M", "磌"), + (0x2F951, "M", "䃣"), + (0x2F952, "M", "𥘦"), + (0x2F953, "M", "祖"), + (0x2F954, "M", "𥚚"), + (0x2F955, "M", "𥛅"), + (0x2F956, "M", "福"), + (0x2F957, "M", "秫"), + (0x2F958, "M", "䄯"), + (0x2F959, "M", "穀"), + (0x2F95A, "M", "穊"), + (0x2F95B, "M", "穏"), + (0x2F95C, "M", "𥥼"), + (0x2F95D, "M", "𥪧"), + (0x2F95F, "X"), + (0x2F960, "M", "䈂"), + (0x2F961, "M", "𥮫"), + (0x2F962, "M", "篆"), + (0x2F963, "M", "築"), + (0x2F964, "M", "䈧"), + (0x2F965, "M", "𥲀"), + (0x2F966, "M", "糒"), + (0x2F967, "M", "䊠"), + (0x2F968, "M", "糨"), + (0x2F969, "M", "糣"), + (0x2F96A, "M", "紀"), + (0x2F96B, "M", "𥾆"), + (0x2F96C, "M", "絣"), + (0x2F96D, "M", "䌁"), + (0x2F96E, "M", "緇"), + (0x2F96F, "M", "縂"), + (0x2F970, "M", "繅"), + (0x2F971, "M", "䌴"), + (0x2F972, "M", "𦈨"), + (0x2F973, "M", "𦉇"), + ] + + +def _seg_80() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F974, "M", "䍙"), + (0x2F975, "M", "𦋙"), + (0x2F976, "M", "罺"), + (0x2F977, "M", "𦌾"), + (0x2F978, "M", "羕"), + (0x2F979, "M", "翺"), + (0x2F97A, "M", "者"), + (0x2F97B, "M", "𦓚"), + (0x2F97C, "M", "𦔣"), + (0x2F97D, "M", "聠"), + (0x2F97E, "M", "𦖨"), + (0x2F97F, "M", "聰"), + (0x2F980, "M", "𣍟"), + (0x2F981, "M", "䏕"), + (0x2F982, "M", "育"), + (0x2F983, "M", "脃"), + (0x2F984, "M", "䐋"), + (0x2F985, "M", "脾"), + (0x2F986, "M", "媵"), + (0x2F987, "M", "𦞧"), + (0x2F988, "M", "𦞵"), + (0x2F989, "M", "𣎓"), + (0x2F98A, "M", "𣎜"), + (0x2F98B, "M", "舁"), + (0x2F98C, "M", "舄"), + (0x2F98D, "M", "辞"), + (0x2F98E, "M", "䑫"), + (0x2F98F, "M", "芑"), + (0x2F990, "M", "芋"), + (0x2F991, "M", "芝"), + (0x2F992, "M", "劳"), + (0x2F993, "M", "花"), + (0x2F994, "M", "芳"), + (0x2F995, "M", "芽"), + (0x2F996, "M", "苦"), + (0x2F997, "M", "𦬼"), + (0x2F998, "M", "若"), + (0x2F999, "M", "茝"), + (0x2F99A, "M", "荣"), + (0x2F99B, "M", "莭"), + (0x2F99C, "M", "茣"), + (0x2F99D, "M", "莽"), + (0x2F99E, "M", "菧"), + (0x2F99F, "M", "著"), + (0x2F9A0, "M", "荓"), + (0x2F9A1, "M", "菊"), + (0x2F9A2, "M", "菌"), + (0x2F9A3, "M", "菜"), + (0x2F9A4, "M", "𦰶"), + (0x2F9A5, "M", "𦵫"), + (0x2F9A6, "M", "𦳕"), + (0x2F9A7, "M", "䔫"), + (0x2F9A8, "M", "蓱"), + (0x2F9A9, "M", "蓳"), + (0x2F9AA, "M", "蔖"), + (0x2F9AB, "M", "𧏊"), + (0x2F9AC, "M", "蕤"), + (0x2F9AD, "M", "𦼬"), + (0x2F9AE, "M", "䕝"), + (0x2F9AF, "M", "䕡"), + (0x2F9B0, "M", "𦾱"), + (0x2F9B1, "M", "𧃒"), + (0x2F9B2, "M", "䕫"), + (0x2F9B3, "M", "虐"), + (0x2F9B4, "M", "虜"), + (0x2F9B5, "M", "虧"), + (0x2F9B6, "M", "虩"), + (0x2F9B7, "M", "蚩"), + (0x2F9B8, "M", "蚈"), + (0x2F9B9, "M", "蜎"), + (0x2F9BA, "M", "蛢"), + (0x2F9BB, "M", "蝹"), + (0x2F9BC, "M", "蜨"), + (0x2F9BD, "M", "蝫"), + (0x2F9BE, "M", "螆"), + (0x2F9BF, "X"), + (0x2F9C0, "M", "蟡"), + (0x2F9C1, "M", "蠁"), + (0x2F9C2, "M", "䗹"), + (0x2F9C3, "M", "衠"), + (0x2F9C4, "M", "衣"), + (0x2F9C5, "M", "𧙧"), + (0x2F9C6, "M", "裗"), + (0x2F9C7, "M", "裞"), + (0x2F9C8, "M", "䘵"), + (0x2F9C9, "M", "裺"), + (0x2F9CA, "M", "㒻"), + (0x2F9CB, "M", "𧢮"), + (0x2F9CC, "M", "𧥦"), + (0x2F9CD, "M", "䚾"), + (0x2F9CE, "M", "䛇"), + (0x2F9CF, "M", "誠"), + (0x2F9D0, "M", "諭"), + (0x2F9D1, "M", "變"), + (0x2F9D2, "M", "豕"), + (0x2F9D3, "M", "𧲨"), + (0x2F9D4, "M", "貫"), + (0x2F9D5, "M", "賁"), + (0x2F9D6, "M", "贛"), + (0x2F9D7, "M", "起"), + ] + + +def _seg_81() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: + return [ + (0x2F9D8, "M", "𧼯"), + (0x2F9D9, "M", "𠠄"), + (0x2F9DA, "M", "跋"), + (0x2F9DB, "M", "趼"), + (0x2F9DC, "M", "跰"), + (0x2F9DD, "M", "𠣞"), + (0x2F9DE, "M", "軔"), + (0x2F9DF, "M", "輸"), + (0x2F9E0, "M", "𨗒"), + (0x2F9E1, "M", "𨗭"), + (0x2F9E2, "M", "邔"), + (0x2F9E3, "M", "郱"), + (0x2F9E4, "M", "鄑"), + (0x2F9E5, "M", "𨜮"), + (0x2F9E6, "M", "鄛"), + (0x2F9E7, "M", "鈸"), + (0x2F9E8, "M", "鋗"), + (0x2F9E9, "M", "鋘"), + (0x2F9EA, "M", "鉼"), + (0x2F9EB, "M", "鏹"), + (0x2F9EC, "M", "鐕"), + (0x2F9ED, "M", "𨯺"), + (0x2F9EE, "M", "開"), + (0x2F9EF, "M", "䦕"), + (0x2F9F0, "M", "閷"), + (0x2F9F1, "M", "𨵷"), + (0x2F9F2, "M", "䧦"), + (0x2F9F3, "M", "雃"), + (0x2F9F4, "M", "嶲"), + (0x2F9F5, "M", "霣"), + (0x2F9F6, "M", "𩅅"), + (0x2F9F7, "M", "𩈚"), + (0x2F9F8, "M", "䩮"), + (0x2F9F9, "M", "䩶"), + (0x2F9FA, "M", "韠"), + (0x2F9FB, "M", "𩐊"), + (0x2F9FC, "M", "䪲"), + (0x2F9FD, "M", "𩒖"), + (0x2F9FE, "M", "頋"), + (0x2FA00, "M", "頩"), + (0x2FA01, "M", "𩖶"), + (0x2FA02, "M", "飢"), + (0x2FA03, "M", "䬳"), + (0x2FA04, "M", "餩"), + (0x2FA05, "M", "馧"), + (0x2FA06, "M", "駂"), + (0x2FA07, "M", "駾"), + (0x2FA08, "M", "䯎"), + (0x2FA09, "M", "𩬰"), + (0x2FA0A, "M", "鬒"), + (0x2FA0B, "M", "鱀"), + (0x2FA0C, "M", "鳽"), + (0x2FA0D, "M", "䳎"), + (0x2FA0E, "M", "䳭"), + (0x2FA0F, "M", "鵧"), + (0x2FA10, "M", "𪃎"), + (0x2FA11, "M", "䳸"), + (0x2FA12, "M", "𪄅"), + (0x2FA13, "M", "𪈎"), + (0x2FA14, "M", "𪊑"), + (0x2FA15, "M", "麻"), + (0x2FA16, "M", "䵖"), + (0x2FA17, "M", "黹"), + (0x2FA18, "M", "黾"), + (0x2FA19, "M", "鼅"), + (0x2FA1A, "M", "鼏"), + (0x2FA1B, "M", "鼖"), + (0x2FA1C, "M", "鼻"), + (0x2FA1D, "M", "𪘀"), + (0x2FA1E, "X"), + (0x30000, "V"), + (0x3134B, "X"), + (0x31350, "V"), + (0x323B0, "X"), + (0xE0100, "I"), + (0xE01F0, "X"), + ] + + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() + + _seg_78() + + _seg_79() + + _seg_80() + + _seg_81() +) # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/METADATA b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/METADATA new file mode 100644 index 0000000..ffef2ff --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/METADATA @@ -0,0 +1,84 @@ +Metadata-Version: 2.4 +Name: Jinja2 +Version: 3.1.6 +Summary: A very fast and expressive template engine. +Maintainer-email: Pallets +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +License-File: LICENSE.txt +Requires-Dist: MarkupSafe>=2.0 +Requires-Dist: Babel>=2.7 ; extra == "i18n" +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/jinja/ +Provides-Extra: i18n + +# Jinja + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +## In A Nutshell + +```jinja +{% extends "base.html" %} +{% block title %}Members{% endblock %} +{% block content %} +

    +{% endblock %} +``` + +## Donate + +The Pallets organization develops and supports Jinja 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.11/site-packages/jinja2-3.1.6.dist-info/RECORD b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/RECORD new file mode 100644 index 0000000..b51accc --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/RECORD @@ -0,0 +1,58 @@ +jinja2-3.1.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.6.dist-info/METADATA,sha256=aMVUj7Z8QTKhOJjZsx7FDGvqKr3ZFdkh8hQ1XDpkmcg,2871 +jinja2-3.1.6.dist-info/RECORD,, +jinja2-3.1.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2-3.1.6.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82 +jinja2-3.1.6.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2-3.1.6.dist-info/licenses/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2/__init__.py,sha256=xxepO9i7DHsqkQrgBEduLtfoz2QCuT6_gbL4XSN1hbU,1928 +jinja2/__pycache__/__init__.cpython-311.pyc,, +jinja2/__pycache__/_identifier.cpython-311.pyc,, +jinja2/__pycache__/async_utils.cpython-311.pyc,, +jinja2/__pycache__/bccache.cpython-311.pyc,, +jinja2/__pycache__/compiler.cpython-311.pyc,, +jinja2/__pycache__/constants.cpython-311.pyc,, +jinja2/__pycache__/debug.cpython-311.pyc,, +jinja2/__pycache__/defaults.cpython-311.pyc,, +jinja2/__pycache__/environment.cpython-311.pyc,, +jinja2/__pycache__/exceptions.cpython-311.pyc,, +jinja2/__pycache__/ext.cpython-311.pyc,, +jinja2/__pycache__/filters.cpython-311.pyc,, +jinja2/__pycache__/idtracking.cpython-311.pyc,, +jinja2/__pycache__/lexer.cpython-311.pyc,, +jinja2/__pycache__/loaders.cpython-311.pyc,, +jinja2/__pycache__/meta.cpython-311.pyc,, +jinja2/__pycache__/nativetypes.cpython-311.pyc,, +jinja2/__pycache__/nodes.cpython-311.pyc,, +jinja2/__pycache__/optimizer.cpython-311.pyc,, +jinja2/__pycache__/parser.cpython-311.pyc,, +jinja2/__pycache__/runtime.cpython-311.pyc,, +jinja2/__pycache__/sandbox.cpython-311.pyc,, +jinja2/__pycache__/tests.cpython-311.pyc,, +jinja2/__pycache__/utils.cpython-311.pyc,, +jinja2/__pycache__/visitor.cpython-311.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=vK-PdsuorOMnWSnEkT3iUJRIkTnYgO2T6MnGxDgHI5o,2834 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=9RpCQl5X88BHllJiPsHPh295Hh0uApvwFJNQuutULeM,74131 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=CnHqCDHd-BVGvti_8ZsTolnXNhA3ECsY-6n_2pwU8Hw,6297 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=9nhrP7Ch-NbGX00wvyr4yy-uhNHq2OCc60ggGrni_fk,61513 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=5PF5eHfh8mXAIxXHHRB2xXbXohi8pE3nHSOxa66uS7E,31875 +jinja2/filters.py,sha256=PQ_Egd9n9jSgtnGQYyF4K5j2nYwhUIulhPnyimkdr-k,55212 +jinja2/idtracking.py,sha256=-ll5lIp73pML3ErUYiIJj7tdmWxcH_IlDv3yA_hiZYo,10555 +jinja2/lexer.py,sha256=LYiYio6br-Tep9nPcupWXsPEtjluw3p1mU-lNBVRUfk,29786 +jinja2/loaders.py,sha256=wIrnxjvcbqh5VwW28NSkfotiDq8qNCxIOSFbGUiSLB4,24055 +jinja2/meta.py,sha256=OTDPkaFvU2Hgvx-6akz7154F8BIWaRmvJcBFvwopHww,4397 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=m1Duzcr6qhZI8JQ6VyJgUNinjAf5bQzijSmDnMsvUx8,34579 +jinja2/optimizer.py,sha256=rJnCRlQ7pZsEEmMhsQDgC_pKyDHxP5TPS6zVPGsgcu8,1651 +jinja2/parser.py,sha256=lLOFy3sEmHc5IaEHRiH1sQVnId2moUQzhyeJZTtdY30,40383 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=gDk-GvdriJXqgsGbHgrcKTP0Yp6zPXzhzrIpCFH3jAU,34249 +jinja2/sandbox.py,sha256=Mw2aitlY2I8la7FYhcX2YG9BtUYcLnD0Gh3d29cDWrY,15009 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=rRp3o9e7ZKS4fyrWRbELyLcpuGVTFcnooaOa1qx_FIk,24129 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/REQUESTED b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/WHEEL b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/WHEEL new file mode 100644 index 0000000..23d2d7e --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.11.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/entry_points.txt b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/entry_points.txt new file mode 100644 index 0000000..abc3eae --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[babel.extractors] +jinja2=jinja2.ext:babel_extract[i18n] + diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.6.dist-info/licenses/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2007 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.11/site-packages/jinja2/__init__.py b/venv/lib/python3.11/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..1a423a3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/__init__.py @@ -0,0 +1,38 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" + +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.6" diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bde856e3dc3d210f1e941e5295421e675e23fcac GIT binary patch literal 2118 zcma)+TTdf56vrI`1SS^}F5wOX?6yKHi0HQ4R@$yqZrxU}LZy`|zl_X`8-|^+N468f zK2?3{H)y{>)o(M8qdZlrRH^C<(!T9ekIfFmyF4^G`RnJukB=|$%ip;0Xx_+JPusOWy20|1y>B0fvdP`xB^_mHN#cl2|QuA7S-bhZWx{bp2U-e z>%dcZ%5VdC8c!RZ1fIb&hNpm=xM_GAcoxqZo&lc2bB3GIe7t}c49@~D;zh%Az)N_^ z@I3G`UN*b{yn$S#N*N|(5b#z{mJbt!9yjJlU1REjb;WNy+C)IGUU=bUZ3Un@5eyc-4- zMmdbLtsjn$TzSP5>AC8hC|7opgbO8MXrwFAULvTJA!jgx1@LouqM%74M}l$2do+M) zyP@DLrc7-+|G*7Fn}vRL_exQp2Xv44=M;?D!!V+!R}xnHZddb|#=cGq-t8$L+|`B} zW8b~qDsVIBFQueHFX})DF7(uSPj1w6;{{iTyu$)Wn$Ep%J4}T!&2t;MF9(vRa`V(2 zR-Rk?o(1$rIH(|ZoLwU65hnrF3#sg#^U%L*JNu!pZhPx@2XgDx4m-@(d%1Ng$2{mn zcQvXf#D7WJcShwzz#4kD119&*Nyx}qL~mCIOR4SCvrc=^X~yIw^&;MeJJa^yP;Pbt zxf7>Kz(NO;#|Ik~KcYl<<{y)Ko1wJER}vzn=X0iLPeFg(v?Q|Xh0z8ZPFy|ew~#pZ|olII27_q=}T%r{euBHT1FtYrkGUmlo2jA|QRW2o=Y zo=?rCm10c0<688)PL#D&v{bd!K>DS~{CiSNXsfQJp=DCbl$L2NGg_J;{gSx3Kw?%~ zb6V!LENEE->5p_&7)i0Djb$w>T2{5VTGl}NWzXwUp&vER`vbiO3%xmNb%|(QUS76n z%r8RPrMS!zdyc2het^jT`hee2mtkrnsle4ZjJGW1DmM`jm+n)jWC zHId2rB1Kl*SNZ*O{xn5aWav?9M}}Id9skd<%EBy}y>U2)_nkj$Ge4E}S3H6n^&c?i Bgd6|> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/_identifier.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/_identifier.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14308aaaaa0f4d339a06e2116cdc1c6235285fc3 GIT binary patch literal 2134 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 Le7DAXHZ}e?FEVwr literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/compiler.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf7c5bca13ec392ed7738c2df63d59ec07953ff6 GIT binary patch literal 112438 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/constants.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/constants.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98031f59958f0d230c8b3e57eab8b267f253154b GIT binary patch literal 1553 zcmX|>J&znk5QcZbAT*K#gGf=Q4)Ds5Aw&cL62{0UghXQX_SEjy(I0dDv8Veb7QX=T zZ-_~eNJuO>bHr1#2cwy)>YnPVx8JJn-yS}kHa!0Ce~!Ptx7qwt6CalG{h0XYDRT-lnwZt*K4nS|Z5jk|nr# zsC~`JQCcSzx;u%Y2X-`J+~bzWwj>imDnO+cd(P2~5$GAF(ZGzpRAG6fR5lbGD0MY; z9H4}hQc-1JY9}egN}3|QfqU{20AV)SxDTUkl7Tr3Neb$>!o3Pg0d>AOKD82*ET#(17_-$8O?3jt zaRwZD0vAd*170|5^l7J~*jB%=(TQE^WQxe0rqp>rEKGp@Vi+qOOr5KU^`mk}IV)2N zr5dsk`5ib<7em1@D3u%CoqbgTpXFq`_ZZPWFrC?smCAk+dJi|rojFy4JbPMdLQAE1 z=MqO>IF9ELm(eNP_m8)KKKkzYi*KI2{Pu^dAD_Ma>G_MVuYTXWvHSMzvmI%7x3{-D zN#$B)U9TnY$a&szVs^`2r!JpAdHQq*oAT-6!!Mp2XLqgn+JCmQ8_>>od$QcU{oqS3 kkrCyq`aaR^N^c(_UcbBDZeKt6@Z(SZ*gU$t^#Sw$0zlq2c>n+a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/debug.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/debug.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92902d38c895b49e61f81ea2e3a622d6db3a5d5f GIT binary patch literal 6713 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 A3;+NC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/environment.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/environment.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26233ac6fa7aed92b8a158dfa374c965f4160338 GIT binary patch literal 80576 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/ext.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/ext.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8b3c1fd2a5886b69c94e610976f869139ad5bcd GIT binary patch literal 43380 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 &7ee<3qaZrC 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/idtracking.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/idtracking.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..80eb29ae9976cb8feefdaab265b6a701d29de53b GIT binary patch literal 19508 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 IjHUR00iJCg761SM literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/loaders.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/loaders.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b888d0010e802c598cbfbfce97cd78d1598f30d5 GIT binary patch literal 34394 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

      Z- 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/meta.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/meta.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0913d065ae22cb62a72ae97445c05e3a82a5fa0b GIT binary patch literal 5698 zcmcgwO>7&-6`m!RqPCc&znGH6<69ax?=vKF>TI-|)JDUVC5GqV<+CP7uV2qmVa>N6PTz)Xu8W`=O0 zvEWyXo5`=hm?$dPKHX4=360PgG|my7P}wpl>p4s1G=WCrxIV8^Lr)XkN>)T+PqF;+ z;5BHx3%)^6Tmb*@C_>z;G_IqRp!lyh#YH7Re2S>}KvD@L^@GI&&O09ygfY@OS`^|9 zpn)d4eTvG-tH6F8OUtpJ5|BI#y0B&mP6E4lro!(Yg4&Iw$~O%Fi?*KJP$AWHHs0%Pn}`uDqb_njZHfS`lDB2=yK;AdAs0mwGBIDB*g#fIxCGvMcZd)GlbewBBAQ4l}OlLlUQ~~R#!+;lPOUWssa{KQ!1fm)N6|-(NdJ{ zW4j@dfFY)tNSJITjMu(Jvdou;=0QtCnmRp{S+Zsg{khn& zV?(BDk--euK%ODy(44Bz$-_fwV#%@05^V;G%TMiTqF9Ajw&%>}pnAB5?n|K?fsMfD z(t&%@fvxV`kyE)BUe8Mt1!*EDP23+o@z>tFz3XB@>dEoz0Zc=-uvlj#rg&~7hDHEF z0#n;^(-}kWv+x21eq)n=f=`s~e9E@9$!v@yUG9$u^l&IgaEJICONZ5XvqnYi?$Y3GL{f)_oSy|&or%%B9^3!{pyoM7-()=}4 z;HzI&e6{?zIfv@#R}i7Ftf`T24MJ z`6_g{&qYP90}fcU5!jlH1{nzG;D`VM!9*f$C|QlQn-Ym%W@WA16G$W!Bbi9>4GLgk zQOW`jWoqHNutQ~7ND@s;B%*?&Hs*-0I2vnULs=Du+x#6=pp(k4C_bMPpD&3X-}4~# zV=77Tb#Iy_1dlC?KXzAszwgv`dkMkgqvQPXgDS2g&Lj8*$jCI5boUaxu>HgL=QK3x z!5n<1+Ha_(M2Q9Y$kEYJE(mr)23FGa}ZlTBi6Ji2ep%UG1w*=D{kZ z>Pn)DP6<~b{Xjd4M@I0qKA7LP%GaEtS>lKhi(y$w8xVCNK%PF0&qJOCfTvqL`*OyB zrOq=n(*XgO%0{b8NK_MZb+ZhNF~SsHiA(#|_+l)cAhQ2+5!iTrVcHYc4A1^c?UprS68{fU~n+uyg zd9kA)cI3p4V&ncoV>Bm5Id0Se1;fQ2xF7r$HvR+>04!F}Hhg%rST)d44+m$^rf~T% zgO6$mU-ejSXoWE9v1-C=H5}gpnzvoL=HmCvaRYZ9C3lUKr=AwQuu^m8f)wG*s<)21 zw~mgRAnc-YxPHzYvm`GTOO489*PMnGZ*|;H&`m)=8?PurxizkfZu|W@>YnPX@1Y(9 zxm+&FG(WAQBh*R8VgoO`xI9}or-r8Gp41Ssx+=2~dPKv$wVZ&4yC2c;<8=fnTABAJ zHiZpb(FnAUIBBgs4Q_E3AOp4~gbB9wDM`VRPEP`SS5JK`Wbj@HD-a(zesH9BP#McQ z-^!3z@gp5J=F15iqc|&5h3&p7K{#kyuoVF<%mD~kNiECUKt^%sa4IuO|&{J8yYcfNC^&CNZXZL21{fbR(UpBUH&c3IAn9MgG zEi@i2p-@9-aevo)v0M{&uWu#Pd|*rbfV`j1hXx9v0pP2l^W!drKEE_q#A(hioN?AzZ=MFnG^|QCe6JxK9 zk4>DPJXdqFVK{C}Q{_a(_Fg0wcOD+&?Z7z0A~+QW&jQFn{sn2I?RTE^1x9_C&G%i> z0j}V5^fpONf$Q4R`7+qq(wjUVku~lul>Hs&939yI0pCe4IftlGdI4V9p};%=b;&CT zLdoM1M9>yg5)xW-XuorPfuLP?6;V&F{wkvGT>bThSG>-ALWmZ{{#^Z4^0x?Zf_$_B zL$a^mRJ)F}3rDw4?0{!NQ^-W%EOEkuUzjNg6Z)85YpbFFU{8sA!zO8#M?(^&u-u)y4>`#$UX$Jl3w Q3MYSDLh$Xe6<6zj0Zkm8#Q*>R literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/nativetypes.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/nativetypes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc6c350ab97246276437698bc092940c73c4cccd GIT binary patch literal 7960 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/nodes.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/nodes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74b59f06b31f61959ca2744593684e2bf8351d4e GIT binary patch literal 64479 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 KdOf;aUGN9f$uqYA literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/optimizer.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/optimizer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e3af5f5c1d1e1a2739ca952e1a51fe1398dbc0a GIT binary patch literal 2849 zcmb7G|7#q_6`$GLTiq9(B+I8twu3V?vXyJoyDGLzTbs7Ft0Yda8fyLGEA4iDJ16aV zZ|5?zr<2?Z=m$YnaEmDp3MHkY7{|qh80)sT0iR9ck}`3rYxuNmxCz(v z6Lqs}QUd*?pR8MDixO_sh7NWSX~B%;r|Ri)8deQ)v!>6&c{k;z-ON!=)pE1zW;tt+ zSBX2kPTU-~9wrER3~$`Z!>)0I6h@p6C?N|=oQX#0)xA4hvQTWqRUH+gXu9^K0H5=WR$qlef@s9IXTNOvTop5)qYLLh2gi{Djgo`bWQQGAQ*S$a&nC1(8bc`~nfg(BLZ}Tk-%|@GJ%w z#1P;lSc6Nn972OZ+=gDI7u4F(83yf^gKHst5Z0coMQ@o0#ex;3f6_~Whyq>}2wI7n zMeY2tdXY{Id<~hZ|;np z?TnpWyY^Xj`0jV!IdlIT?|Od{e-Mw{ozv$!r_b$V&v&xtx6Si=u!&TV^cos~ZSR*r zehpscq)eeM8E(c+LiK=p12v`ZEvPxxVLftF1Ea*zmDSV+sZuw+K3s<03N5F>e_5G@ zV>D{dCc`2kEds~?*^vnSxlF^7`GG*h5YT~$mT!_aZ4(=MadQa<#(aTlu>~VC75A%p zpl~B&@)&%glx=%~7uxonaXeR-xnhs^9IQ}dK-S3ask0kqCpERLA9);@+Sifk$VC-d zw_Erf&<}%r6yCk_kPz?CO=1ir%R`uY3~$_O{iJErMcOw0On*u|(oQ^}zoT!{un#o> zJHI-82Gc^?X)>^`FJbFQ^7T$fsayRE<&X<}L#En>OHcHf0R+NeLbhqG7citvYUnB5 z{%QLVcg zYou$Du`|DI{-$-e)ft`MTG$@F_~^$#;^)Ix;_rs}G)0ELcF+Ce+m$q z$1`#YH(&vkBS?mUM2XA6s)jMj9iUv{zHi%*#Aje$VT$}H23r>lB&Tp<6$k*^`*jVP z1h58)bu5|R&7ZjcdN+Z+nHL{4z-sj@ zbt#7P2NDZC;-UTy1bjtl*GN$lLIg;j(Bs==Jbs=K=np)*WO{q>d6F>Ke+Y=t!mjz^ w_TbaCOnTwoh5O%!n4uRQUDuzF_{TNf`EN2ZK>@!1CHF?ZK<<}cF{SPM4@wfgb^rhX literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/parser.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/parser.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43c630411fdcce6136f11254b5d03c544004597c GIT binary patch literal 60025 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/runtime.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/runtime.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7e047bc6878105f0f511ec7190f2f276feaf8b6 GIT binary patch literal 51112 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 Rsk1ooE``3gN)%h$|9^-VO?3bO literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/sandbox.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/sandbox.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fd09b15bea548cbb27ebcf3c245870e7328608e GIT binary patch literal 19220 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 Kg7haUjQ<6;HiaDk literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/utils.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71d679ccc5ac9ad7d5e258f0e9f9168992b11191 GIT binary patch literal 37556 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 M@4i|kfbkdqKT1s?cK`qY literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/visitor.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/visitor.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbd52aa76d4a57596186960c4297324e936a27df GIT binary patch literal 5697 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 Rn@RraSNQhpExMSQ{|6d*pY{L% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/_identifier.py b/venv/lib/python3.11/site-packages/jinja2/_identifier.py new file mode 100644 index 0000000..928c150 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/venv/lib/python3.11/site-packages/jinja2/async_utils.py b/venv/lib/python3.11/site-packages/jinja2/async_utils.py new file mode 100644 index 0000000..f0c1402 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/async_utils.py @@ -0,0 +1,99 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +if t.TYPE_CHECKING: + import typing_extensions as te + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True # type: ignore[attr-defined] + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return value + + +class _IteratorToAsyncIterator(t.Generic[V]): + def __init__(self, iterator: "t.Iterator[V]"): + self._iterator = iterator + + def __aiter__(self) -> "te.Self": + return self + + async def __anext__(self) -> V: + try: + return next(self._iterator) + except StopIteration as e: + raise StopAsyncIteration(e.value) from e + + +def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + return iterable.__aiter__() + else: + return _IteratorToAsyncIterator(iter(iterable)) + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/venv/lib/python3.11/site-packages/jinja2/bccache.py b/venv/lib/python3.11/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..ada8b09 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/bccache.py @@ -0,0 +1,408 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" + +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: ... + + def set( + self, key: str, value: bytes, timeout: t.Optional[int] = None + ) -> None: ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/venv/lib/python3.11/site-packages/jinja2/compiler.py b/venv/lib/python3.11/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..a4ff6a1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/compiler.py @@ -0,0 +1,1998 @@ +"""Compiles nodes from the parser into Python code.""" + +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(new_func, f) # type: ignore[return-value] + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: # noqa E721 + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "te.Self": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "te.Self": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in ( + (self.filters, visitor.filters, "filters"), + ( + self.tests, + visitor.tests, + "tests", + ), + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(sorted(vars)): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, sorted(public_names))) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import async_exported + from .runtime import exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline("agen = parent_template.root_render_func(context)") + self.writeline("try:") + self.indent() + self.writeline("async for event in agen:") + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent() + self.writeline("finally: await agen.aclose()") + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline(f"gen = context.blocks[{node.name!r}][0]({context})") + self.writeline("try:") + self.indent() + self.writeline( + f"{self.choose_async()}for event in gen:", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + self.outdent() + self.writeline( + f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}" + ) + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + def loop_body() -> None: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.with_context: + self.writeline( + f"gen = template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)}))" + ) + self.writeline("try:") + self.indent() + self.writeline(f"{self.choose_async()}for event in gen:") + loop_body() + self.outdent() + self.writeline( + f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + loop_body() + else: + self.writeline("yield from template._get_default_module()._body_stream") + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + # The position will contain the template name, and will be formatted + # into a string that will be compiled into an f-string. Curly braces + # in the name must be replaced with escapes so that they will not be + # executed as part of the f-string. + position = self.position(node).replace("{", "{{").replace("}", "}}") + message = ( + "the template {included_template.__name__!r}" + f" (imported on {position})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + + # ``a.b`` is allowed for assignment, and is parsed as an NSRef. However, + # it is only valid if it references a Namespace object. Emit a check for + # that for each ref here, before assignment code is emitted. This can't + # be done in visit_NSRef as the ref could be in the middle of a tuple. + seen_refs: t.Set[str] = set() + + for nsref in node.find_all(nodes.NSRef): + if nsref.name in seen_refs: + # Only emit the check for each reference once, in case the same + # ref is used multiple times in a tuple, `ns.a, ns.b = c, d`. + continue + + seen_refs.add(nsref.name) + ref = frame.symbols.ref(nsref.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRef is a dotted assignment target a.b=c, but uses a[b]=c internally. + # visit_Assign emits code to validate that each ref is to a Namespace + # object only. That can't be emitted here as the ref could be in the + # middle of a tuple assignment. + ref = frame.symbols.ref(node.name) + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/venv/lib/python3.11/site-packages/jinja2/constants.py b/venv/lib/python3.11/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/venv/lib/python3.11/site-packages/jinja2/debug.py b/venv/lib/python3.11/site-packages/jinja2/debug.py new file mode 100644 index 0000000..eeeeee7 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: t.Optional[Context] = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/venv/lib/python3.11/site-packages/jinja2/defaults.py b/venv/lib/python3.11/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/venv/lib/python3.11/site-packages/jinja2/environment.py b/venv/lib/python3.11/site-packages/jinja2/environment.py new file mode 100644 index 0000000..0fc6e5b --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/environment.py @@ -0,0 +1,1672 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" + +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS # type: ignore[attr-defined] +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS # type: ignore[attr-defined] +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping[t.Any, t.Any]], +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: # noqa E721 + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: _env_bound) -> _env_bound: + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = missing, + ) -> "te.Self": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.5 + ``enable_async`` is applied correctly. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "