From aa0b8fd99911277f35fa871713d78d35d8699aaa Mon Sep 17 00:00:00 2001 From: root Date: Mon, 9 Dec 2024 16:17:23 +0100 Subject: [PATCH 1/2] update --- create.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create.sh b/create.sh index 2648aaa..27d98f8 100644 --- a/create.sh +++ b/create.sh @@ -34,7 +34,7 @@ BRIDGE="vmbr0" MEMORY="4096" CORES="4" STORAGE="btrfs" # Opslaglocatie -OSKEUZE="5" # Naam en versie van het besturingssysteem, bijv. "Debian 12" +OSKEUZE="2" # Naam en versie van het besturingssysteem, bijv. "Debian 12" TEMPLATE="n" # Of de VM als template moet worden ingesteld (j/n) SSH_KEY_TEXT="" From e03a8d7fd1ee21441b8ae2f42ae74f60dd7bbbd0 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 9 Dec 2024 16:17:52 +0100 Subject: [PATCH 2/2] update --- .venv/bin/Activate.ps1 | 247 + .venv/bin/activate | 69 + .venv/bin/activate.csh | 26 + .venv/bin/activate.fish | 69 + .venv/bin/flask | 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 + .../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 + .../site-packages/_distutils_hack/__init__.py | 222 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 11154 bytes .../__pycache__/override.cpython-311.pyc | Bin 0 -> 311 bytes .../site-packages/_distutils_hack/override.py | 1 + .../blinker-1.9.0.dist-info/INSTALLER | 1 + .../blinker-1.9.0.dist-info/LICENSE.txt | 20 + .../blinker-1.9.0.dist-info/METADATA | 60 + .../blinker-1.9.0.dist-info/RECORD | 12 + .../blinker-1.9.0.dist-info/WHEEL | 4 + .../site-packages/blinker/__init__.py | 17 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 602 bytes .../__pycache__/_utilities.cpython-311.pyc | Bin 0 -> 3087 bytes .../blinker/__pycache__/base.cpython-311.pyc | Bin 0 -> 23619 bytes .../site-packages/blinker/_utilities.py | 64 + .../python3.11/site-packages/blinker/base.py | 512 + .../python3.11/site-packages/blinker/py.typed | 0 .../click-8.1.7.dist-info/INSTALLER | 1 + .../click-8.1.7.dist-info/LICENSE.rst | 28 + .../click-8.1.7.dist-info/METADATA | 103 + .../click-8.1.7.dist-info/RECORD | 39 + .../site-packages/click-8.1.7.dist-info/WHEEL | 5 + .../click-8.1.7.dist-info/top_level.txt | 1 + .../site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3672 bytes .../click/__pycache__/_compat.cpython-311.pyc | Bin 0 -> 28663 bytes .../__pycache__/_termui_impl.cpython-311.pyc | Bin 0 -> 33060 bytes .../__pycache__/_textwrap.cpython-311.pyc | Bin 0 -> 2633 bytes .../__pycache__/_winconsole.cpython-311.pyc | Bin 0 -> 13323 bytes .../click/__pycache__/core.cpython-311.pyc | Bin 0 -> 142405 bytes .../__pycache__/decorators.cpython-311.pyc | Bin 0 -> 25427 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 16186 bytes .../__pycache__/formatting.cpython-311.pyc | Bin 0 -> 15678 bytes .../click/__pycache__/globals.cpython-311.pyc | Bin 0 -> 3360 bytes .../click/__pycache__/parser.cpython-311.pyc | Bin 0 -> 23122 bytes .../shell_completion.cpython-311.pyc | Bin 0 -> 23971 bytes .../click/__pycache__/termui.cpython-311.pyc | Bin 0 -> 34467 bytes .../click/__pycache__/testing.cpython-311.pyc | Bin 0 -> 25755 bytes .../click/__pycache__/types.cpython-311.pyc | Bin 0 -> 53657 bytes .../click/__pycache__/utils.cpython-311.pyc | Bin 0 -> 27966 bytes .../python3.11/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 739 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../python3.11/site-packages/click/core.py | 3042 ++++++ .../site-packages/click/decorators.py | 561 ++ .../site-packages/click/exceptions.py | 288 + .../site-packages/click/formatting.py | 301 + .../python3.11/site-packages/click/globals.py | 68 + .../python3.11/site-packages/click/parser.py | 529 + .../python3.11/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .../python3.11/site-packages/click/termui.py | 784 ++ .../python3.11/site-packages/click/testing.py | 479 + .../python3.11/site-packages/click/types.py | 1089 +++ .../python3.11/site-packages/click/utils.py | 624 ++ .../site-packages/distutils-precedence.pth | 1 + .../flask-3.1.0.dist-info/INSTALLER | 1 + .../flask-3.1.0.dist-info/LICENSE.txt | 28 + .../flask-3.1.0.dist-info/METADATA | 81 + .../flask-3.1.0.dist-info/RECORD | 58 + .../flask-3.1.0.dist-info/REQUESTED | 0 .../site-packages/flask-3.1.0.dist-info/WHEEL | 4 + .../flask-3.1.0.dist-info/entry_points.txt | 3 + .../site-packages/flask/__init__.py | 60 + .../site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3165 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 254 bytes .../flask/__pycache__/app.cpython-311.pyc | Bin 0 -> 65068 bytes .../__pycache__/blueprints.cpython-311.pyc | Bin 0 -> 5351 bytes .../flask/__pycache__/cli.cpython-311.pyc | Bin 0 -> 47895 bytes .../flask/__pycache__/config.cpython-311.pyc | Bin 0 -> 17212 bytes .../flask/__pycache__/ctx.cpython-311.pyc | Bin 0 -> 20895 bytes .../__pycache__/debughelpers.cpython-311.pyc | Bin 0 -> 10206 bytes .../flask/__pycache__/globals.cpython-311.pyc | Bin 0 -> 2217 bytes .../flask/__pycache__/helpers.cpython-311.pyc | Bin 0 -> 26533 bytes .../flask/__pycache__/logging.cpython-311.pyc | Bin 0 -> 3447 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 0 -> 18635 bytes .../flask/__pycache__/signals.cpython-311.pyc | Bin 0 -> 1358 bytes .../__pycache__/templating.cpython-311.pyc | Bin 0 -> 10645 bytes .../flask/__pycache__/testing.cpython-311.pyc | Bin 0 -> 14600 bytes .../flask/__pycache__/typing.cpython-311.pyc | Bin 0 -> 3676 bytes .../flask/__pycache__/views.cpython-311.pyc | Bin 0 -> 7454 bytes .../__pycache__/wrappers.cpython-311.pyc | Bin 0 -> 10845 bytes .../lib/python3.11/site-packages/flask/app.py | 1536 +++ .../site-packages/flask/blueprints.py | 128 + .../lib/python3.11/site-packages/flask/cli.py | 1133 +++ .../python3.11/site-packages/flask/config.py | 367 + .../lib/python3.11/site-packages/flask/ctx.py | 449 + .../site-packages/flask/debughelpers.py | 178 + .../python3.11/site-packages/flask/globals.py | 51 + .../python3.11/site-packages/flask/helpers.py | 634 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6869 bytes .../json/__pycache__/provider.cpython-311.pyc | Bin 0 -> 9984 bytes .../json/__pycache__/tag.cpython-311.pyc | Bin 0 -> 16577 bytes .../site-packages/flask/json/provider.py | 215 + .../site-packages/flask/json/tag.py | 327 + .../python3.11/site-packages/flask/logging.py | 79 + .../python3.11/site-packages/flask/py.typed | 0 .../site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-311.pyc | Bin 0 -> 35436 bytes .../__pycache__/blueprints.cpython-311.pyc | Bin 0 -> 32545 bytes .../__pycache__/scaffold.cpython-311.pyc | Bin 0 -> 31424 bytes .../site-packages/flask/sansio/app.py | 964 ++ .../site-packages/flask/sansio/blueprints.py | 632 ++ .../site-packages/flask/sansio/scaffold.py | 792 ++ .../site-packages/flask/sessions.py | 398 + .../python3.11/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 219 + .../python3.11/site-packages/flask/testing.py | 297 + .../python3.11/site-packages/flask/typing.py | 90 + .../python3.11/site-packages/flask/views.py | 191 + .../site-packages/flask/wrappers.py | 257 + .../itsdangerous-2.2.0.dist-info/INSTALLER | 1 + .../itsdangerous-2.2.0.dist-info/LICENSE.txt | 28 + .../itsdangerous-2.2.0.dist-info/METADATA | 60 + .../itsdangerous-2.2.0.dist-info/RECORD | 22 + .../itsdangerous-2.2.0.dist-info/WHEEL | 4 + .../site-packages/itsdangerous/__init__.py | 38 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1987 bytes .../__pycache__/_json.cpython-311.pyc | Bin 0 -> 1364 bytes .../__pycache__/encoding.cpython-311.pyc | Bin 0 -> 2943 bytes .../__pycache__/exc.cpython-311.pyc | Bin 0 -> 4814 bytes .../__pycache__/serializer.cpython-311.pyc | Bin 0 -> 15720 bytes .../__pycache__/signer.cpython-311.pyc | Bin 0 -> 12473 bytes .../__pycache__/timed.cpython-311.pyc | Bin 0 -> 9740 bytes .../__pycache__/url_safe.cpython-311.pyc | Bin 0 -> 4125 bytes .../site-packages/itsdangerous/_json.py | 18 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 106 + .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 406 + .../site-packages/itsdangerous/signer.py | 266 + .../site-packages/itsdangerous/timed.py | 228 + .../site-packages/itsdangerous/url_safe.py | 83 + .../jinja2-3.1.4.dist-info/INSTALLER | 1 + .../jinja2-3.1.4.dist-info/LICENSE.txt | 28 + .../jinja2-3.1.4.dist-info/METADATA | 76 + .../jinja2-3.1.4.dist-info/RECORD | 57 + .../jinja2-3.1.4.dist-info/WHEEL | 4 + .../jinja2-3.1.4.dist-info/entry_points.txt | 3 + .../site-packages/jinja2/__init__.py | 38 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2113 bytes .../__pycache__/_identifier.cpython-311.pyc | Bin 0 -> 2129 bytes .../__pycache__/async_utils.cpython-311.pyc | Bin 0 -> 4565 bytes .../__pycache__/bccache.cpython-311.pyc | Bin 0 -> 20911 bytes .../__pycache__/compiler.cpython-311.pyc | Bin 0 -> 110495 bytes .../__pycache__/constants.cpython-311.pyc | Bin 0 -> 1548 bytes .../jinja2/__pycache__/debug.cpython-311.pyc | Bin 0 -> 6708 bytes .../__pycache__/defaults.cpython-311.pyc | Bin 0 -> 1714 bytes .../__pycache__/environment.cpython-311.pyc | Bin 0 -> 80693 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8599 bytes .../jinja2/__pycache__/ext.cpython-311.pyc | Bin 0 -> 43366 bytes .../__pycache__/filters.cpython-311.pyc | Bin 0 -> 77325 bytes .../__pycache__/idtracking.cpython-311.pyc | Bin 0 -> 19534 bytes .../jinja2/__pycache__/lexer.cpython-311.pyc | Bin 0 -> 35609 bytes .../__pycache__/loaders.cpython-311.pyc | Bin 0 -> 33018 bytes .../jinja2/__pycache__/meta.cpython-311.pyc | Bin 0 -> 5693 bytes .../__pycache__/nativetypes.cpython-311.pyc | Bin 0 -> 7955 bytes .../jinja2/__pycache__/nodes.cpython-311.pyc | Bin 0 -> 64474 bytes .../__pycache__/optimizer.cpython-311.pyc | Bin 0 -> 2844 bytes .../jinja2/__pycache__/parser.cpython-311.pyc | Bin 0 -> 59631 bytes .../__pycache__/runtime.cpython-311.pyc | Bin 0 -> 50682 bytes .../__pycache__/sandbox.cpython-311.pyc | Bin 0 -> 18914 bytes .../jinja2/__pycache__/tests.cpython-311.pyc | Bin 0 -> 9264 bytes .../jinja2/__pycache__/utils.cpython-311.pyc | Bin 0 -> 37116 bytes .../__pycache__/visitor.cpython-311.pyc | Bin 0 -> 5692 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../site-packages/jinja2/bccache.py | 408 + .../site-packages/jinja2/compiler.py | 1960 ++++ .../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 | 1675 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../python3.11/site-packages/jinja2/ext.py | 870 ++ .../site-packages/jinja2/filters.py | 1866 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.11/site-packages/jinja2/lexer.py | 868 ++ .../site-packages/jinja2/loaders.py | 667 ++ .../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 | 1041 ++ .../python3.11/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1056 ++ .../site-packages/jinja2/sandbox.py | 429 + .../python3.11/site-packages/jinja2/tests.py | 256 + .../python3.11/site-packages/jinja2/utils.py | 755 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 395 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 25730 bytes .../__pycache__/_native.cpython-311.pyc | Bin 0 -> 681 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 -> 766 bytes .../pip/__pycache__/__main__.cpython-311.pyc | Bin 0 -> 1075 bytes .../__pip-runner__.cpython-311.pyc | Bin 0 -> 2503 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 949 bytes .../__pycache__/build_env.cpython-311.pyc | Bin 0 -> 16069 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 14694 bytes .../__pycache__/configuration.cpython-311.pyc | Bin 0 -> 19225 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 38354 bytes .../__pycache__/main.cpython-311.pyc | Bin 0 -> 749 bytes .../__pycache__/pyproject.cpython-311.pyc | Bin 0 -> 5517 bytes .../self_outdated_check.cpython-311.pyc | Bin 0 -> 11319 bytes .../__pycache__/wheel_builder.cpython-311.pyc | Bin 0 -> 15989 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 -> 284 bytes .../autocompletion.cpython-311.pyc | Bin 0 -> 10074 bytes .../__pycache__/base_command.cpython-311.pyc | Bin 0 -> 11072 bytes .../__pycache__/cmdoptions.cpython-311.pyc | Bin 0 -> 32971 bytes .../command_context.cpython-311.pyc | Bin 0 -> 2106 bytes .../cli/__pycache__/main.cpython-311.pyc | Bin 0 -> 2361 bytes .../__pycache__/main_parser.cpython-311.pyc | Bin 0 -> 5520 bytes .../cli/__pycache__/parser.cpython-311.pyc | Bin 0 -> 17021 bytes .../__pycache__/progress_bars.cpython-311.pyc | Bin 0 -> 3168 bytes .../__pycache__/req_command.cpython-311.pyc | Bin 0 -> 20133 bytes .../cli/__pycache__/spinners.cpython-311.pyc | Bin 0 -> 8833 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 0 -> 372 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 -> 4452 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 10551 bytes .../__pycache__/check.cpython-311.pyc | Bin 0 -> 2302 bytes .../__pycache__/completion.cpython-311.pyc | Bin 0 -> 5464 bytes .../__pycache__/configuration.cpython-311.pyc | Bin 0 -> 14893 bytes .../__pycache__/debug.cpython-311.pyc | Bin 0 -> 12001 bytes .../__pycache__/download.cpython-311.pyc | Bin 0 -> 7808 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 0 -> 4153 bytes .../commands/__pycache__/hash.cpython-311.pyc | Bin 0 -> 3354 bytes .../commands/__pycache__/help.cpython-311.pyc | Bin 0 -> 1966 bytes .../__pycache__/index.cpython-311.pyc | Bin 0 -> 7789 bytes .../__pycache__/inspect.cpython-311.pyc | Bin 0 -> 4442 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 35371 bytes .../commands/__pycache__/list.cpython-311.pyc | Bin 0 -> 17503 bytes .../__pycache__/search.cpython-311.pyc | Bin 0 -> 8948 bytes .../commands/__pycache__/show.cpython-311.pyc | Bin 0 -> 11291 bytes .../__pycache__/uninstall.cpython-311.pyc | Bin 0 -> 5142 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 9948 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 -> 1034 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 2406 bytes .../__pycache__/installed.cpython-311.pyc | Bin 0 -> 1543 bytes .../__pycache__/sdist.cpython-311.pyc | Bin 0 -> 8945 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 2137 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 -> 238 bytes .../__pycache__/collector.cpython-311.pyc | Bin 0 -> 24544 bytes .../package_finder.cpython-311.pyc | Bin 0 -> 44216 bytes .../index/__pycache__/sources.cpython-311.pyc | Bin 0 -> 11020 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 -> 18176 bytes .../__pycache__/_distutils.cpython-311.pyc | Bin 0 -> 7585 bytes .../__pycache__/_sysconfig.cpython-311.pyc | Bin 0 -> 8880 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 4001 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 -> 6409 bytes .../__pycache__/_json.cpython-311.pyc | Bin 0 -> 3563 bytes .../metadata/__pycache__/base.cpython-311.pyc | Bin 0 -> 38008 bytes .../__pycache__/pkg_resources.cpython-311.pyc | Bin 0 -> 16856 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 -> 355 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 3562 bytes .../__pycache__/_dists.cpython-311.pyc | Bin 0 -> 14578 bytes .../__pycache__/_envs.cpython-311.pyc | Bin 0 -> 12416 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 -> 272 bytes .../__pycache__/candidate.cpython-311.pyc | Bin 0 -> 2091 bytes .../__pycache__/direct_url.cpython-311.pyc | Bin 0 -> 12254 bytes .../format_control.cpython-311.pyc | Bin 0 -> 4655 bytes .../models/__pycache__/index.cpython-311.pyc | Bin 0 -> 1897 bytes .../installation_report.cpython-311.pyc | Bin 0 -> 2611 bytes .../models/__pycache__/link.cpython-311.pyc | Bin 0 -> 26443 bytes .../models/__pycache__/scheme.cpython-311.pyc | Bin 0 -> 1263 bytes .../__pycache__/search_scope.cpython-311.pyc | Bin 0 -> 5826 bytes .../selection_prefs.cpython-311.pyc | Bin 0 -> 1994 bytes .../__pycache__/target_python.cpython-311.pyc | Bin 0 -> 4756 bytes .../models/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 6419 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 -> 260 bytes .../network/__pycache__/auth.cpython-311.pyc | Bin 0 -> 19064 bytes .../network/__pycache__/cache.cpython-311.pyc | Bin 0 -> 5183 bytes .../__pycache__/download.cpython-311.pyc | Bin 0 -> 9575 bytes .../__pycache__/lazy_wheel.cpython-311.pyc | Bin 0 -> 13021 bytes .../__pycache__/session.cpython-311.pyc | Bin 0 -> 21288 bytes .../network/__pycache__/utils.cpython-311.pyc | Bin 0 -> 2409 bytes .../__pycache__/xmlrpc.cpython-311.pyc | Bin 0 -> 3188 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 -> 198 bytes .../__pycache__/check.cpython-311.pyc | Bin 0 -> 6631 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 0 -> 11594 bytes .../__pycache__/prepare.cpython-311.pyc | Bin 0 -> 26378 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 204 bytes .../__pycache__/build_tracker.cpython-311.pyc | Bin 0 -> 8127 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 0 -> 2275 bytes .../metadata_editable.cpython-311.pyc | Bin 0 -> 2311 bytes .../metadata_legacy.cpython-311.pyc | Bin 0 -> 3711 bytes .../build/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 1941 bytes .../wheel_editable.cpython-311.pyc | Bin 0 -> 2385 bytes .../__pycache__/wheel_legacy.cpython-311.pyc | Bin 0 -> 4492 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 -> 272 bytes .../editable_legacy.cpython-311.pyc | Bin 0 -> 2268 bytes .../__pycache__/legacy.cpython-311.pyc | Bin 0 -> 6108 bytes .../install/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 39994 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 -> 4444 bytes .../__pycache__/constructors.cpython-311.pyc | Bin 0 -> 20703 bytes .../req/__pycache__/req_file.cpython-311.pyc | Bin 0 -> 22432 bytes .../__pycache__/req_install.cpython-311.pyc | Bin 0 -> 40344 bytes .../req/__pycache__/req_set.cpython-311.pyc | Bin 0 -> 6000 bytes .../__pycache__/req_uninstall.cpython-311.pyc | Bin 0 -> 36998 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 -> 198 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 1369 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 205 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 0 -> 23791 bytes .../_internal/resolution/legacy/resolver.py | 600 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 209 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 9622 bytes .../__pycache__/candidates.cpython-311.pyc | Bin 0 -> 28832 bytes .../__pycache__/factory.cpython-311.pyc | Bin 0 -> 31976 bytes .../found_candidates.cpython-311.pyc | Bin 0 -> 6757 bytes .../__pycache__/provider.cpython-311.pyc | Bin 0 -> 11051 bytes .../__pycache__/reporter.cpython-311.pyc | Bin 0 -> 4654 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 11119 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 0 -> 12306 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 -> 193 bytes .../utils/__pycache__/_log.cpython-311.pyc | Bin 0 -> 2014 bytes .../utils/__pycache__/appdirs.cpython-311.pyc | Bin 0 -> 2552 bytes .../utils/__pycache__/compat.cpython-311.pyc | Bin 0 -> 2260 bytes .../compatibility_tags.cpython-311.pyc | Bin 0 -> 6752 bytes .../__pycache__/datetime.cpython-311.pyc | Bin 0 -> 710 bytes .../__pycache__/deprecation.cpython-311.pyc | Bin 0 -> 7083 bytes .../direct_url_helpers.cpython-311.pyc | Bin 0 -> 3716 bytes .../distutils_args.cpython-311.pyc | Bin 0 -> 1460 bytes .../__pycache__/egg_link.cpython-311.pyc | Bin 0 -> 3231 bytes .../__pycache__/encoding.cpython-311.pyc | Bin 0 -> 2316 bytes .../__pycache__/entrypoints.cpython-311.pyc | Bin 0 -> 4238 bytes .../__pycache__/filesystem.cpython-311.pyc | Bin 0 -> 8223 bytes .../__pycache__/filetypes.cpython-311.pyc | Bin 0 -> 1309 bytes .../utils/__pycache__/glibc.cpython-311.pyc | Bin 0 -> 2552 bytes .../utils/__pycache__/hashes.cpython-311.pyc | Bin 0 -> 8330 bytes .../inject_securetransport.cpython-311.pyc | Bin 0 -> 1327 bytes .../utils/__pycache__/logging.cpython-311.pyc | Bin 0 -> 15452 bytes .../utils/__pycache__/misc.cpython-311.pyc | Bin 0 -> 37694 bytes .../utils/__pycache__/models.cpython-311.pyc | Bin 0 -> 2933 bytes .../__pycache__/packaging.cpython-311.pyc | Bin 0 -> 2800 bytes .../setuptools_build.cpython-311.pyc | Bin 0 -> 6097 bytes .../__pycache__/subprocess.cpython-311.pyc | Bin 0 -> 9887 bytes .../__pycache__/temp_dir.cpython-311.pyc | Bin 0 -> 11414 bytes .../__pycache__/unpacking.cpython-311.pyc | Bin 0 -> 12889 bytes .../utils/__pycache__/urls.cpython-311.pyc | Bin 0 -> 2686 bytes .../__pycache__/virtualenv.cpython-311.pyc | Bin 0 -> 4933 bytes .../utils/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 7103 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 -> 628 bytes .../vcs/__pycache__/bazaar.cpython-311.pyc | Bin 0 -> 5853 bytes .../vcs/__pycache__/git.cpython-311.pyc | Bin 0 -> 21517 bytes .../vcs/__pycache__/mercurial.cpython-311.pyc | Bin 0 -> 8699 bytes .../__pycache__/subversion.cpython-311.pyc | Bin 0 -> 14596 bytes .../versioncontrol.cpython-311.pyc | Bin 0 -> 31865 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 -> 5606 bytes .../_vendor/__pycache__/six.cpython-311.pyc | Bin 0 -> 46408 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 97438 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 835 bytes .../__pycache__/_cmd.cpython-311.pyc | Bin 0 -> 2690 bytes .../__pycache__/adapter.cpython-311.pyc | Bin 0 -> 5497 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 3771 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 1128 bytes .../__pycache__/controller.cpython-311.pyc | Bin 0 -> 16443 bytes .../__pycache__/filewrapper.cpython-311.pyc | Bin 0 -> 4230 bytes .../__pycache__/heuristics.cpython-311.pyc | Bin 0 -> 6675 bytes .../__pycache__/serialize.cpython-311.pyc | Bin 0 -> 8390 bytes .../__pycache__/wrapper.cpython-311.pyc | Bin 0 -> 956 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 -> 410 bytes .../__pycache__/file_cache.cpython-311.pyc | Bin 0 -> 8393 bytes .../__pycache__/redis_cache.cpython-311.pyc | Bin 0 -> 2490 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 -> 335 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 736 bytes .../certifi/__pycache__/core.cpython-311.pyc | Bin 0 -> 3978 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 -> 5067 bytes .../__pycache__/big5freq.cpython-311.pyc | Bin 0 -> 27197 bytes .../__pycache__/big5prober.cpython-311.pyc | Bin 0 -> 1672 bytes .../chardistribution.cpython-311.pyc | Bin 0 -> 11264 bytes .../charsetgroupprober.cpython-311.pyc | Bin 0 -> 4294 bytes .../__pycache__/charsetprober.cpython-311.pyc | Bin 0 -> 5540 bytes .../codingstatemachine.cpython-311.pyc | Bin 0 -> 3991 bytes .../codingstatemachinedict.cpython-311.pyc | Bin 0 -> 947 bytes .../__pycache__/cp949prober.cpython-311.pyc | Bin 0 -> 1681 bytes .../chardet/__pycache__/enums.cpython-311.pyc | Bin 0 -> 3382 bytes .../__pycache__/escprober.cpython-311.pyc | Bin 0 -> 4898 bytes .../chardet/__pycache__/escsm.cpython-311.pyc | Bin 0 -> 12637 bytes .../__pycache__/eucjpprober.cpython-311.pyc | Bin 0 -> 4724 bytes .../__pycache__/euckrfreq.cpython-311.pyc | Bin 0 -> 12080 bytes .../__pycache__/euckrprober.cpython-311.pyc | Bin 0 -> 1673 bytes .../__pycache__/euctwfreq.cpython-311.pyc | Bin 0 -> 27202 bytes .../__pycache__/euctwprober.cpython-311.pyc | Bin 0 -> 1673 bytes .../__pycache__/gb2312freq.cpython-311.pyc | Bin 0 -> 19124 bytes .../__pycache__/gb2312prober.cpython-311.pyc | Bin 0 -> 1688 bytes .../__pycache__/hebrewprober.cpython-311.pyc | Bin 0 -> 5677 bytes .../__pycache__/jisfreq.cpython-311.pyc | Bin 0 -> 22153 bytes .../__pycache__/johabfreq.cpython-311.pyc | Bin 0 -> 84657 bytes .../__pycache__/johabprober.cpython-311.pyc | Bin 0 -> 1679 bytes .../__pycache__/jpcntx.cpython-311.pyc | Bin 0 -> 40161 bytes .../langbulgarianmodel.cpython-311.pyc | Bin 0 -> 85831 bytes .../langgreekmodel.cpython-311.pyc | Bin 0 -> 79253 bytes .../langhebrewmodel.cpython-311.pyc | Bin 0 -> 80015 bytes .../langhungarianmodel.cpython-311.pyc | Bin 0 -> 85785 bytes .../langrussianmodel.cpython-311.pyc | Bin 0 -> 108732 bytes .../__pycache__/langthaimodel.cpython-311.pyc | Bin 0 -> 80193 bytes .../langturkishmodel.cpython-311.pyc | Bin 0 -> 80032 bytes .../__pycache__/latin1prober.cpython-311.pyc | Bin 0 -> 7328 bytes .../macromanprober.cpython-311.pyc | Bin 0 -> 7495 bytes .../mbcharsetprober.cpython-311.pyc | Bin 0 -> 4116 bytes .../mbcsgroupprober.cpython-311.pyc | Bin 0 -> 1986 bytes .../__pycache__/mbcssm.cpython-311.pyc | Bin 0 -> 31726 bytes .../__pycache__/resultdict.cpython-311.pyc | Bin 0 -> 765 bytes .../sbcharsetprober.cpython-311.pyc | Bin 0 -> 6391 bytes .../sbcsgroupprober.cpython-311.pyc | Bin 0 -> 2936 bytes .../__pycache__/sjisprober.cpython-311.pyc | Bin 0 -> 4829 bytes .../universaldetector.cpython-311.pyc | Bin 0 -> 12457 bytes .../__pycache__/utf1632prober.cpython-311.pyc | Bin 0 -> 10577 bytes .../__pycache__/utf8prober.cpython-311.pyc | Bin 0 -> 3464 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 500 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 -> 197 bytes .../__pycache__/chardetect.cpython-311.pyc | Bin 0 -> 4336 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 -> 202 bytes .../__pycache__/languages.cpython-311.pyc | Bin 0 -> 10802 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 -> 569 bytes .../colorama/__pycache__/ansi.cpython-311.pyc | Bin 0 -> 4567 bytes .../__pycache__/ansitowin32.cpython-311.pyc | Bin 0 -> 16213 bytes .../__pycache__/initialise.cpython-311.pyc | Bin 0 -> 3930 bytes .../__pycache__/win32.cpython-311.pyc | Bin 0 -> 7918 bytes .../__pycache__/winterm.cpython-311.pyc | Bin 0 -> 9144 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 -> 200 bytes .../__pycache__/ansi_test.cpython-311.pyc | Bin 0 -> 5845 bytes .../ansitowin32_test.cpython-311.pyc | Bin 0 -> 21512 bytes .../initialise_test.cpython-311.pyc | Bin 0 -> 14139 bytes .../__pycache__/isatty_test.cpython-311.pyc | Bin 0 -> 6704 bytes .../tests/__pycache__/utils.cpython-311.pyc | Bin 0 -> 2879 bytes .../__pycache__/winterm_test.cpython-311.pyc | Bin 0 -> 7232 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 -> 1438 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 52304 bytes .../__pycache__/database.cpython-311.pyc | Bin 0 -> 72092 bytes .../distlib/__pycache__/index.cpython-311.pyc | Bin 0 -> 26681 bytes .../__pycache__/locators.cpython-311.pyc | Bin 0 -> 65857 bytes .../__pycache__/manifest.cpython-311.pyc | Bin 0 -> 17024 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 8160 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 0 -> 47108 bytes .../__pycache__/resources.cpython-311.pyc | Bin 0 -> 18987 bytes .../__pycache__/scripts.cpython-311.pyc | Bin 0 -> 21263 bytes .../distlib/__pycache__/util.cpython-311.pyc | Bin 0 -> 97442 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 34569 bytes .../distlib/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 60373 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 -> 1191 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 325 bytes .../distro/__pycache__/distro.cpython-311.pyc | Bin 0 -> 57724 bytes .../pip/_vendor/distro/distro.py | 1399 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1092 bytes .../idna/__pycache__/codec.cpython-311.pyc | Bin 0 -> 5383 bytes .../idna/__pycache__/compat.cpython-311.pyc | Bin 0 -> 1009 bytes .../idna/__pycache__/core.cpython-311.pyc | Bin 0 -> 19444 bytes .../idna/__pycache__/idnadata.cpython-311.pyc | Bin 0 -> 38968 bytes .../__pycache__/intranges.cpython-311.pyc | Bin 0 -> 2977 bytes .../__pycache__/package_data.cpython-311.pyc | Bin 0 -> 212 bytes .../__pycache__/uts46data.cpython-311.pyc | Bin 0 -> 163192 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 -> 2071 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 2372 bytes .../msgpack/__pycache__/ext.cpython-311.pyc | Bin 0 -> 9158 bytes .../__pycache__/fallback.cpython-311.pyc | Bin 0 -> 47185 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 -> 636 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 557 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13223 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 7991 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3679 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16519 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7634 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34357 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21342 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6677 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21869 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 -> 158225 bytes .../__pycache__/py31compat.cpython-311.pyc | Bin 0 -> 978 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 -> 12924 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 2121 bytes .../__pycache__/android.cpython-311.pyc | Bin 0 -> 6351 bytes .../__pycache__/api.cpython-311.pyc | Bin 0 -> 7178 bytes .../__pycache__/macos.cpython-311.pyc | Bin 0 -> 4588 bytes .../__pycache__/unix.cpython-311.pyc | Bin 0 -> 11020 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 307 bytes .../__pycache__/windows.cpython-311.pyc | Bin 0 -> 9956 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 -> 3839 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 775 bytes .../__pycache__/cmdline.cpython-311.pyc | Bin 0 -> 30286 bytes .../__pycache__/console.cpython-311.pyc | Bin 0 -> 3038 bytes .../__pycache__/filter.cpython-311.pyc | Bin 0 -> 3499 bytes .../__pycache__/formatter.cpython-311.pyc | Bin 0 -> 3865 bytes .../__pycache__/lexer.cpython-311.pyc | Bin 0 -> 40393 bytes .../__pycache__/modeline.cpython-311.pyc | Bin 0 -> 1718 bytes .../__pycache__/plugin.cpython-311.pyc | Bin 0 -> 3731 bytes .../__pycache__/regexopt.cpython-311.pyc | Bin 0 -> 5025 bytes .../__pycache__/scanner.cpython-311.pyc | Bin 0 -> 4880 bytes .../__pycache__/sphinxext.cpython-311.pyc | Bin 0 -> 8311 bytes .../__pycache__/style.cpython-311.pyc | Bin 0 -> 7419 bytes .../__pycache__/token.cpython-311.pyc | Bin 0 -> 7459 bytes .../__pycache__/unistring.cpython-311.pyc | Bin 0 -> 33793 bytes .../pygments/__pycache__/util.cpython-311.pyc | Bin 0 -> 14586 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 -> 40099 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 143 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6865 bytes .../__pycache__/_mapping.cpython-311.pyc | Bin 0 -> 4147 bytes .../__pycache__/bbcode.cpython-311.pyc | Bin 0 -> 4473 bytes .../__pycache__/groff.cpython-311.pyc | Bin 0 -> 7806 bytes .../__pycache__/html.cpython-311.pyc | Bin 0 -> 42591 bytes .../__pycache__/img.cpython-311.pyc | Bin 0 -> 28563 bytes .../__pycache__/irc.cpython-311.pyc | Bin 0 -> 7666 bytes .../__pycache__/latex.cpython-311.pyc | Bin 0 -> 21799 bytes .../__pycache__/other.cpython-311.pyc | Bin 0 -> 7627 bytes .../__pycache__/pangomarkup.cpython-311.pyc | Bin 0 -> 3171 bytes .../__pycache__/rtf.cpython-311.pyc | Bin 0 -> 6838 bytes .../__pycache__/svg.cpython-311.pyc | Bin 0 -> 9658 bytes .../__pycache__/terminal.cpython-311.pyc | Bin 0 -> 6037 bytes .../__pycache__/terminal256.cpython-311.pyc | Bin 0 -> 16403 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 -> 15142 bytes .../__pycache__/_mapping.cpython-311.pyc | Bin 0 -> 62773 bytes .../lexers/__pycache__/python.cpython-311.pyc | Bin 0 -> 43974 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 -> 4452 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 -> 8342 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8456 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14778 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277664 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12920 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53621 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36304 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19500 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15358 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14257 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 -> 28023 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 -> 700 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 398 bytes .../__pycache__/_impl.cpython-311.pyc | Bin 0 -> 16664 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 -> 1160 bytes .../__pycache__/_in_process.cpython-311.pyc | Bin 0 -> 16482 bytes .../_in_process/_in_process.py | 353 + .../pip/_vendor/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6444 bytes .../__pycache__/__version__.cpython-311.pyc | Bin 0 -> 581 bytes .../_internal_utils.cpython-311.pyc | Bin 0 -> 2078 bytes .../__pycache__/adapters.cpython-311.pyc | Bin 0 -> 24881 bytes .../requests/__pycache__/api.cpython-311.pyc | Bin 0 -> 7426 bytes .../requests/__pycache__/auth.cpython-311.pyc | Bin 0 -> 14625 bytes .../__pycache__/certs.cpython-311.pyc | Bin 0 -> 977 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 1803 bytes .../__pycache__/cookies.cpython-311.pyc | Bin 0 -> 27105 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8520 bytes .../requests/__pycache__/help.cpython-311.pyc | Bin 0 -> 4515 bytes .../__pycache__/hooks.cpython-311.pyc | Bin 0 -> 1245 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 38776 bytes .../__pycache__/packages.cpython-311.pyc | Bin 0 -> 825 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 0 -> 29614 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 0 -> 6232 bytes .../__pycache__/structures.cpython-311.pyc | Bin 0 -> 6217 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 40131 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 -> 748 bytes .../__pycache__/providers.cpython-311.pyc | Bin 0 -> 7067 bytes .../__pycache__/reporters.cpython-311.pyc | Bin 0 -> 2797 bytes .../__pycache__/resolvers.cpython-311.pyc | Bin 0 -> 25243 bytes .../__pycache__/structs.cpython-311.pyc | Bin 0 -> 11325 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 203 bytes .../collections_abc.cpython-311.pyc | Bin 0 -> 478 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 -> 7491 bytes .../rich/__pycache__/__main__.cpython-311.pyc | Bin 0 -> 11569 bytes .../__pycache__/_cell_widths.cpython-311.pyc | Bin 0 -> 7830 bytes .../__pycache__/_emoji_codes.cpython-311.pyc | Bin 0 -> 208517 bytes .../_emoji_replace.cpython-311.pyc | Bin 0 -> 1929 bytes .../_export_format.cpython-311.pyc | Bin 0 -> 2334 bytes .../__pycache__/_extension.cpython-311.pyc | Bin 0 -> 630 bytes .../rich/__pycache__/_inspect.cpython-311.pyc | Bin 0 -> 14182 bytes .../__pycache__/_log_render.cpython-311.pyc | Bin 0 -> 4764 bytes .../rich/__pycache__/_loop.cpython-311.pyc | Bin 0 -> 2110 bytes .../__pycache__/_null_file.cpython-311.pyc | Bin 0 -> 4675 bytes .../__pycache__/_palettes.cpython-311.pyc | Bin 0 -> 5246 bytes .../rich/__pycache__/_pick.cpython-311.pyc | Bin 0 -> 791 bytes .../rich/__pycache__/_ratio.cpython-311.pyc | Bin 0 -> 7929 bytes .../__pycache__/_spinners.cpython-311.pyc | Bin 0 -> 13679 bytes .../rich/__pycache__/_stack.cpython-311.pyc | Bin 0 -> 1125 bytes .../rich/__pycache__/_timer.cpython-311.pyc | Bin 0 -> 978 bytes .../_win32_console.cpython-311.pyc | Bin 0 -> 30166 bytes .../rich/__pycache__/_windows.cpython-311.pyc | Bin 0 -> 2825 bytes .../_windows_renderer.cpython-311.pyc | Bin 0 -> 4016 bytes .../rich/__pycache__/_wrap.cpython-311.pyc | Bin 0 -> 2781 bytes .../rich/__pycache__/abc.cpython-311.pyc | Bin 0 -> 1922 bytes .../rich/__pycache__/align.cpython-311.pyc | Bin 0 -> 13471 bytes .../rich/__pycache__/ansi.cpython-311.pyc | Bin 0 -> 10447 bytes .../rich/__pycache__/bar.cpython-311.pyc | Bin 0 -> 4544 bytes .../rich/__pycache__/box.cpython-311.pyc | Bin 0 -> 12986 bytes .../rich/__pycache__/cells.cpython-311.pyc | Bin 0 -> 6436 bytes .../rich/__pycache__/color.cpython-311.pyc | Bin 0 -> 27567 bytes .../__pycache__/color_triplet.cpython-311.pyc | Bin 0 -> 1870 bytes .../rich/__pycache__/columns.cpython-311.pyc | Bin 0 -> 10641 bytes .../rich/__pycache__/console.cpython-311.pyc | Bin 0 -> 123157 bytes .../__pycache__/constrain.cpython-311.pyc | Bin 0 -> 2462 bytes .../__pycache__/containers.cpython-311.pyc | Bin 0 -> 10803 bytes .../rich/__pycache__/control.cpython-311.pyc | Bin 0 -> 11894 bytes .../default_styles.cpython-311.pyc | Bin 0 -> 12494 bytes .../rich/__pycache__/diagnose.cpython-311.pyc | Bin 0 -> 1817 bytes .../rich/__pycache__/emoji.cpython-311.pyc | Bin 0 -> 4795 bytes .../rich/__pycache__/errors.cpython-311.pyc | Bin 0 -> 2326 bytes .../__pycache__/file_proxy.cpython-311.pyc | Bin 0 -> 3774 bytes .../rich/__pycache__/filesize.cpython-311.pyc | Bin 0 -> 3298 bytes .../__pycache__/highlighter.cpython-311.pyc | Bin 0 -> 10985 bytes .../rich/__pycache__/json.cpython-311.pyc | Bin 0 -> 6678 bytes .../rich/__pycache__/jupyter.cpython-311.pyc | Bin 0 -> 6401 bytes .../rich/__pycache__/layout.cpython-311.pyc | Bin 0 -> 23308 bytes .../rich/__pycache__/live.cpython-311.pyc | Bin 0 -> 21129 bytes .../__pycache__/live_render.cpython-311.pyc | Bin 0 -> 5142 bytes .../rich/__pycache__/logging.cpython-311.pyc | Bin 0 -> 14513 bytes .../rich/__pycache__/markup.cpython-311.pyc | Bin 0 -> 10435 bytes .../rich/__pycache__/measure.cpython-311.pyc | Bin 0 -> 7268 bytes .../rich/__pycache__/padding.cpython-311.pyc | Bin 0 -> 7484 bytes .../rich/__pycache__/pager.cpython-311.pyc | Bin 0 -> 2242 bytes .../rich/__pycache__/palette.cpython-311.pyc | Bin 0 -> 5975 bytes .../rich/__pycache__/panel.cpython-311.pyc | Bin 0 -> 12731 bytes .../rich/__pycache__/pretty.cpython-311.pyc | Bin 0 -> 44824 bytes .../rich/__pycache__/progress.cpython-311.pyc | Bin 0 -> 82703 bytes .../__pycache__/progress_bar.cpython-311.pyc | Bin 0 -> 11009 bytes .../rich/__pycache__/prompt.cpython-311.pyc | Bin 0 -> 16375 bytes .../rich/__pycache__/protocol.cpython-311.pyc | Bin 0 -> 2093 bytes .../rich/__pycache__/region.cpython-311.pyc | Bin 0 -> 656 bytes .../rich/__pycache__/repr.cpython-311.pyc | Bin 0 -> 7655 bytes .../rich/__pycache__/rule.cpython-311.pyc | Bin 0 -> 7694 bytes .../rich/__pycache__/scope.cpython-311.pyc | Bin 0 -> 4348 bytes .../rich/__pycache__/screen.cpython-311.pyc | Bin 0 -> 2771 bytes .../rich/__pycache__/segment.cpython-311.pyc | Bin 0 -> 31538 bytes .../rich/__pycache__/spinner.cpython-311.pyc | Bin 0 -> 6887 bytes .../rich/__pycache__/status.cpython-311.pyc | Bin 0 -> 6755 bytes .../rich/__pycache__/style.cpython-311.pyc | Bin 0 -> 34328 bytes .../rich/__pycache__/styled.cpython-311.pyc | Bin 0 -> 2436 bytes .../rich/__pycache__/syntax.cpython-311.pyc | Bin 0 -> 42530 bytes .../rich/__pycache__/table.cpython-311.pyc | Bin 0 -> 48797 bytes .../terminal_theme.cpython-311.pyc | Bin 0 -> 3702 bytes .../rich/__pycache__/text.cpython-311.pyc | Bin 0 -> 65213 bytes .../rich/__pycache__/theme.cpython-311.pyc | Bin 0 -> 7140 bytes .../rich/__pycache__/themes.cpython-311.pyc | Bin 0 -> 352 bytes .../__pycache__/traceback.cpython-311.pyc | Bin 0 -> 31666 bytes .../rich/__pycache__/tree.cpython-311.pyc | Bin 0 -> 12523 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 -> 27790 bytes .../__pycache__/_asyncio.cpython-311.pyc | Bin 0 -> 4797 bytes .../__pycache__/_utils.cpython-311.pyc | Bin 0 -> 2062 bytes .../__pycache__/after.cpython-311.pyc | Bin 0 -> 1689 bytes .../__pycache__/before.cpython-311.pyc | Bin 0 -> 1523 bytes .../__pycache__/before_sleep.cpython-311.pyc | Bin 0 -> 2100 bytes .../tenacity/__pycache__/nap.cpython-311.pyc | Bin 0 -> 1562 bytes .../__pycache__/retry.cpython-311.pyc | Bin 0 -> 15036 bytes .../tenacity/__pycache__/stop.cpython-311.pyc | Bin 0 -> 5890 bytes .../__pycache__/tornadoweb.cpython-311.pyc | Bin 0 -> 2908 bytes .../tenacity/__pycache__/wait.cpython-311.pyc | Bin 0 -> 13362 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 -> 407 bytes .../tomli/__pycache__/_parser.cpython-311.pyc | Bin 0 -> 30846 bytes .../tomli/__pycache__/_re.cpython-311.pyc | Bin 0 -> 4486 bytes .../tomli/__pycache__/_types.cpython-311.pyc | Bin 0 -> 399 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 -> 3705 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 18293 bytes .../__pycache__/_version.cpython-311.pyc | Bin 0 -> 215 bytes .../__pycache__/connection.cpython-311.pyc | Bin 0 -> 21889 bytes .../connectionpool.cpython-311.pyc | Bin 0 -> 37632 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 16119 bytes .../__pycache__/fields.cpython-311.pyc | Bin 0 -> 11412 bytes .../__pycache__/filepost.cpython-311.pyc | Bin 0 -> 4493 bytes .../__pycache__/poolmanager.cpython-311.pyc | Bin 0 -> 21816 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 6656 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 36539 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 -> 201 bytes .../_appengine_environ.cpython-311.pyc | Bin 0 -> 1940 bytes .../__pycache__/appengine.cpython-311.pyc | Bin 0 -> 12147 bytes .../__pycache__/ntlmpool.cpython-311.pyc | Bin 0 -> 6224 bytes .../__pycache__/pyopenssl.cpython-311.pyc | Bin 0 -> 25733 bytes .../securetransport.cpython-311.pyc | Bin 0 -> 36840 bytes .../contrib/__pycache__/socks.cpython-311.pyc | Bin 0 -> 8085 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 218 bytes .../__pycache__/bindings.cpython-311.pyc | Bin 0 -> 16965 bytes .../__pycache__/low_level.cpython-311.pyc | Bin 0 -> 15602 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 -> 202 bytes .../packages/__pycache__/six.cpython-311.pyc | Bin 0 -> 46444 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 212 bytes .../__pycache__/makefile.cpython-311.pyc | Bin 0 -> 1959 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 -> 1404 bytes .../__pycache__/connection.cpython-311.pyc | Bin 0 -> 5131 bytes .../util/__pycache__/proxy.cpython-311.pyc | Bin 0 -> 1713 bytes .../util/__pycache__/queue.cpython-311.pyc | Bin 0 -> 1496 bytes .../util/__pycache__/request.cpython-311.pyc | Bin 0 -> 4616 bytes .../util/__pycache__/response.cpython-311.pyc | Bin 0 -> 3485 bytes .../util/__pycache__/retry.cpython-311.pyc | Bin 0 -> 22753 bytes .../util/__pycache__/ssl_.cpython-311.pyc | Bin 0 -> 16816 bytes .../ssl_match_hostname.cpython-311.pyc | Bin 0 -> 5795 bytes .../__pycache__/ssltransport.cpython-311.pyc | Bin 0 -> 11624 bytes .../util/__pycache__/timeout.cpython-311.pyc | Bin 0 -> 11032 bytes .../util/__pycache__/url.cpython-311.pyc | Bin 0 -> 17556 bytes .../util/__pycache__/wait.cpython-311.pyc | Bin 0 -> 4998 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 -> 12878 bytes .../__pycache__/labels.cpython-311.pyc | Bin 0 -> 7278 bytes .../__pycache__/mklabels.cpython-311.pyc | Bin 0 -> 3206 bytes .../__pycache__/tests.cpython-311.pyc | Bin 0 -> 11184 bytes .../x_user_defined.cpython-311.pyc | Bin 0 -> 3558 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 -> 156109 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 195 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 97412 bytes .../_vendor/__pycache__/zipp.cpython-311.pyc | Bin 0 -> 15988 bytes .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 829 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 10746 bytes .../__pycache__/_common.cpython-311.pyc | Bin 0 -> 4273 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 5558 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1391 bytes .../__pycache__/_legacy.cpython-311.pyc | Bin 0 -> 6489 bytes .../__pycache__/abc.cpython-311.pyc | Bin 0 -> 7490 bytes .../__pycache__/readers.cpython-311.pyc | Bin 0 -> 8364 bytes .../__pycache__/simple.cpython-311.pyc | Bin 0 -> 6386 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 -> 202 bytes .../__pycache__/context.cpython-311.pyc | Bin 0 -> 10977 bytes .../__pycache__/functools.cpython-311.pyc | Bin 0 -> 20288 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 -> 26605 bytes .../_vendor/more_itertools/__init__.py | 6 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 374 bytes .../__pycache__/more.cpython-311.pyc | Bin 0 -> 169496 bytes .../__pycache__/recipes.cpython-311.pyc | Bin 0 -> 33516 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 -> 646 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 567 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13233 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 8001 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3689 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16538 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7653 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34367 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21352 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6687 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21879 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 -> 12827 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 2119 bytes .../__pycache__/android.cpython-311.pyc | Bin 0 -> 6361 bytes .../__pycache__/api.cpython-311.pyc | Bin 0 -> 7188 bytes .../__pycache__/macos.cpython-311.pyc | Bin 0 -> 4598 bytes .../__pycache__/unix.cpython-311.pyc | Bin 0 -> 11030 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 317 bytes .../__pycache__/windows.cpython-311.pyc | Bin 0 -> 9966 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 -> 8340 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8466 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14788 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277640 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12930 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53631 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36314 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19510 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15368 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14267 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 -> 28003 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 -> 4318 bytes .../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 -> 13923 bytes .../_deprecation_warning.cpython-311.pyc | Bin 0 -> 639 bytes .../__pycache__/_entry_points.cpython-311.pyc | Bin 0 -> 5196 bytes .../__pycache__/_imp.cpython-311.pyc | Bin 0 -> 3652 bytes .../__pycache__/_importlib.cpython-311.pyc | Bin 0 -> 1952 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1151 bytes .../__pycache__/_path.cpython-311.pyc | Bin 0 -> 1472 bytes .../__pycache__/_reqs.cpython-311.pyc | Bin 0 -> 1133 bytes .../__pycache__/archive_util.cpython-311.pyc | Bin 0 -> 10161 bytes .../__pycache__/build_meta.cpython-311.pyc | Bin 0 -> 28144 bytes .../__pycache__/dep_util.cpython-311.pyc | Bin 0 -> 1287 bytes .../__pycache__/depends.cpython-311.pyc | Bin 0 -> 7972 bytes .../__pycache__/discovery.cpython-311.pyc | Bin 0 -> 31125 bytes .../__pycache__/dist.cpython-311.pyc | Bin 0 -> 63792 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 2948 bytes .../__pycache__/extension.cpython-311.pyc | Bin 0 -> 6804 bytes .../__pycache__/glob.cpython-311.pyc | Bin 0 -> 6561 bytes .../__pycache__/installer.cpython-311.pyc | Bin 0 -> 5611 bytes .../__pycache__/launch.cpython-311.pyc | Bin 0 -> 1527 bytes .../__pycache__/logging.cpython-311.pyc | Bin 0 -> 2094 bytes .../__pycache__/monkey.cpython-311.pyc | Bin 0 -> 7004 bytes .../__pycache__/msvc.cpython-311.pyc | Bin 0 -> 64177 bytes .../__pycache__/namespaces.cpython-311.pyc | Bin 0 -> 5659 bytes .../__pycache__/package_index.cpython-311.pyc | Bin 0 -> 60897 bytes .../__pycache__/py34compat.cpython-311.pyc | Bin 0 -> 714 bytes .../__pycache__/sandbox.cpython-311.pyc | Bin 0 -> 27330 bytes .../__pycache__/unicode_utils.cpython-311.pyc | Bin 0 -> 1816 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 434 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 15490 bytes .../windows_support.cpython-311.pyc | Bin 0 -> 1431 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 14 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 558 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 8528 bytes .../__pycache__/_functools.cpython-311.pyc | Bin 0 -> 860 bytes .../__pycache__/_log.cpython-311.pyc | Bin 0 -> 277 bytes .../__pycache__/_macos_compat.cpython-311.pyc | Bin 0 -> 569 bytes .../__pycache__/_msvccompiler.cpython-311.pyc | Bin 0 -> 25071 bytes .../__pycache__/archive_util.cpython-311.pyc | Bin 0 -> 10619 bytes .../__pycache__/bcppcompiler.cpython-311.pyc | Bin 0 -> 13445 bytes .../__pycache__/ccompiler.cpython-311.pyc | Bin 0 -> 46314 bytes .../__pycache__/cmd.cpython-311.pyc | Bin 0 -> 18838 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 6039 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 9929 bytes .../cygwinccompiler.cpython-311.pyc | Bin 0 -> 13623 bytes .../__pycache__/debug.cpython-311.pyc | Bin 0 -> 321 bytes .../__pycache__/dep_util.cpython-311.pyc | Bin 0 -> 3983 bytes .../__pycache__/dir_util.cpython-311.pyc | Bin 0 -> 10364 bytes .../__pycache__/dist.cpython-311.pyc | Bin 0 -> 55487 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 6794 bytes .../__pycache__/extension.cpython-311.pyc | Bin 0 -> 10175 bytes .../__pycache__/fancy_getopt.cpython-311.pyc | Bin 0 -> 17234 bytes .../__pycache__/file_util.cpython-311.pyc | Bin 0 -> 10668 bytes .../__pycache__/filelist.cpython-311.pyc | Bin 0 -> 17608 bytes .../__pycache__/log.cpython-311.pyc | Bin 0 -> 2692 bytes .../__pycache__/msvc9compiler.cpython-311.pyc | Bin 0 -> 33557 bytes .../__pycache__/msvccompiler.cpython-311.pyc | Bin 0 -> 26969 bytes .../__pycache__/py38compat.cpython-311.pyc | Bin 0 -> 621 bytes .../__pycache__/py39compat.cpython-311.pyc | Bin 0 -> 989 bytes .../__pycache__/spawn.cpython-311.pyc | Bin 0 -> 4433 bytes .../__pycache__/sysconfig.cpython-311.pyc | Bin 0 -> 22070 bytes .../__pycache__/text_file.cpython-311.pyc | Bin 0 -> 11270 bytes .../__pycache__/unixccompiler.cpython-311.pyc | Bin 0 -> 16493 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 20844 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 11346 bytes .../versionpredicate.cpython-311.pyc | Bin 0 -> 7623 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 -> 541 bytes .../_framework_compat.cpython-311.pyc | Bin 0 -> 2782 bytes .../command/__pycache__/bdist.cpython-311.pyc | Bin 0 -> 6000 bytes .../__pycache__/bdist_dumb.cpython-311.pyc | Bin 0 -> 5720 bytes .../__pycache__/bdist_rpm.cpython-311.pyc | Bin 0 -> 23254 bytes .../command/__pycache__/build.cpython-311.pyc | Bin 0 -> 6055 bytes .../__pycache__/build_clib.cpython-311.pyc | Bin 0 -> 7763 bytes .../__pycache__/build_ext.cpython-311.pyc | Bin 0 -> 30273 bytes .../__pycache__/build_py.cpython-311.pyc | Bin 0 -> 17599 bytes .../__pycache__/build_scripts.cpython-311.pyc | Bin 0 -> 7853 bytes .../command/__pycache__/check.cpython-311.pyc | Bin 0 -> 7509 bytes .../command/__pycache__/clean.cpython-311.pyc | Bin 0 -> 3185 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 16222 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 29374 bytes .../__pycache__/install_data.cpython-311.pyc | Bin 0 -> 3762 bytes .../install_egg_info.cpython-311.pyc | Bin 0 -> 5217 bytes .../install_headers.cpython-311.pyc | Bin 0 -> 2350 bytes .../__pycache__/install_lib.cpython-311.pyc | Bin 0 -> 8671 bytes .../install_scripts.cpython-311.pyc | Bin 0 -> 3157 bytes .../__pycache__/py37compat.cpython-311.pyc | Bin 0 -> 1538 bytes .../__pycache__/register.cpython-311.pyc | Bin 0 -> 15556 bytes .../command/__pycache__/sdist.cpython-311.pyc | Bin 0 -> 23768 bytes .../__pycache__/upload.cpython-311.pyc | Bin 0 -> 10422 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 -> 192 bytes .../__pycache__/ordered_set.cpython-311.pyc | Bin 0 -> 21778 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 107609 bytes .../_vendor/__pycache__/zipp.cpython-311.pyc | Bin 0 -> 15985 bytes .../_vendor/importlib_metadata/__init__.py | 1047 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 58231 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 3844 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 2191 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 2713 bytes .../__pycache__/_functools.cpython-311.pyc | Bin 0 -> 3631 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 2594 bytes .../__pycache__/_meta.cpython-311.pyc | Bin 0 -> 2998 bytes .../__pycache__/_text.cpython-311.pyc | Bin 0 -> 4389 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 -> 826 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 10743 bytes .../__pycache__/_common.cpython-311.pyc | Bin 0 -> 4270 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 5555 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1388 bytes .../__pycache__/_legacy.cpython-311.pyc | Bin 0 -> 6486 bytes .../__pycache__/abc.cpython-311.pyc | Bin 0 -> 7487 bytes .../__pycache__/readers.cpython-311.pyc | Bin 0 -> 8361 bytes .../__pycache__/simple.cpython-311.pyc | Bin 0 -> 6383 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 -> 199 bytes .../__pycache__/context.cpython-311.pyc | Bin 0 -> 10974 bytes .../__pycache__/functools.cpython-311.pyc | Bin 0 -> 20279 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 -> 26593 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 292 bytes .../__pycache__/more.cpython-311.pyc | Bin 0 -> 149179 bytes .../__pycache__/recipes.cpython-311.pyc | Bin 0 -> 23761 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 -> 643 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 564 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13230 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 7998 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3686 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16532 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7647 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34364 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21349 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6684 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21876 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 -> 8337 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8463 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14785 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277637 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12927 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53628 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36311 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19507 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15365 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14264 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 -> 28000 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 -> 414 bytes .../tomli/__pycache__/_parser.cpython-311.pyc | Bin 0 -> 30853 bytes .../tomli/__pycache__/_re.cpython-311.pyc | Bin 0 -> 4493 bytes .../tomli/__pycache__/_types.cpython-311.pyc | Bin 0 -> 406 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 -> 633 bytes .../command/__pycache__/alias.cpython-311.pyc | Bin 0 -> 3900 bytes .../__pycache__/bdist_egg.cpython-311.pyc | Bin 0 -> 25582 bytes .../__pycache__/bdist_rpm.cpython-311.pyc | Bin 0 -> 2188 bytes .../command/__pycache__/build.cpython-311.pyc | Bin 0 -> 6988 bytes .../__pycache__/build_clib.cpython-311.pyc | Bin 0 -> 4163 bytes .../__pycache__/build_ext.cpython-311.pyc | Bin 0 -> 22008 bytes .../__pycache__/build_py.cpython-311.pyc | Bin 0 -> 23174 bytes .../__pycache__/develop.cpython-311.pyc | Bin 0 -> 10916 bytes .../__pycache__/dist_info.cpython-311.pyc | Bin 0 -> 7978 bytes .../__pycache__/easy_install.cpython-311.pyc | Bin 0 -> 121498 bytes .../editable_wheel.cpython-311.pyc | Bin 0 -> 51411 bytes .../__pycache__/egg_info.cpython-311.pyc | Bin 0 -> 40836 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 6813 bytes .../install_egg_info.cpython-311.pyc | Bin 0 -> 5339 bytes .../__pycache__/install_lib.cpython-311.pyc | Bin 0 -> 8410 bytes .../install_scripts.cpython-311.pyc | Bin 0 -> 4277 bytes .../__pycache__/py36compat.cpython-311.pyc | Bin 0 -> 8034 bytes .../__pycache__/register.cpython-311.pyc | Bin 0 -> 1124 bytes .../__pycache__/rotate.cpython-311.pyc | Bin 0 -> 4184 bytes .../__pycache__/saveopts.cpython-311.pyc | Bin 0 -> 1364 bytes .../command/__pycache__/sdist.cpython-311.pyc | Bin 0 -> 13436 bytes .../__pycache__/setopt.cpython-311.pyc | Bin 0 -> 7676 bytes .../command/__pycache__/test.cpython-311.pyc | Bin 0 -> 14617 bytes .../__pycache__/upload.cpython-311.pyc | Bin 0 -> 1088 bytes .../__pycache__/upload_docs.cpython-311.pyc | Bin 0 -> 11939 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 -> 2028 bytes .../_apply_pyprojecttoml.cpython-311.pyc | Bin 0 -> 22837 bytes .../config/__pycache__/expand.cpython-311.pyc | Bin 0 -> 28242 bytes .../__pycache__/pyprojecttoml.cpython-311.pyc | Bin 0 -> 27873 bytes .../__pycache__/setupcfg.cpython-311.pyc | Bin 0 -> 33282 bytes .../setuptools/config/_apply_pyprojecttoml.py | 384 + .../config/_validate_pyproject/__init__.py | 34 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2316 bytes .../error_reporting.cpython-311.pyc | Bin 0 -> 20207 bytes .../extra_validations.cpython-311.pyc | Bin 0 -> 1865 bytes .../fastjsonschema_exceptions.cpython-311.pyc | Bin 0 -> 3240 bytes ...fastjsonschema_validations.cpython-311.pyc | Bin 0 -> 192638 bytes .../__pycache__/formats.cpython-311.pyc | Bin 0 -> 14355 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 -> 4392 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 | 1162 +++ .../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 + .../werkzeug-3.1.3.dist-info/INSTALLER | 1 + .../werkzeug-3.1.3.dist-info/LICENSE.txt | 28 + .../werkzeug-3.1.3.dist-info/METADATA | 99 + .../werkzeug-3.1.3.dist-info/RECORD | 116 + .../werkzeug-3.1.3.dist-info/WHEEL | 4 + .../site-packages/werkzeug/__init__.py | 4 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 392 bytes .../__pycache__/_internal.cpython-311.pyc | Bin 0 -> 10683 bytes .../__pycache__/_reloader.cpython-311.pyc | Bin 0 -> 23128 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 36958 bytes .../__pycache__/formparser.cpython-311.pyc | Bin 0 -> 17992 bytes .../werkzeug/__pycache__/http.cpython-311.pyc | Bin 0 -> 54748 bytes .../__pycache__/local.cpython-311.pyc | Bin 0 -> 31328 bytes .../__pycache__/security.cpython-311.pyc | Bin 0 -> 7762 bytes .../__pycache__/serving.cpython-311.pyc | Bin 0 -> 50437 bytes .../werkzeug/__pycache__/test.cpython-311.pyc | Bin 0 -> 64244 bytes .../__pycache__/testapp.cpython-311.pyc | Bin 0 -> 9536 bytes .../werkzeug/__pycache__/urls.cpython-311.pyc | Bin 0 -> 9025 bytes .../__pycache__/user_agent.cpython-311.pyc | Bin 0 -> 2316 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 30215 bytes .../werkzeug/__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 26876 bytes .../site-packages/werkzeug/_internal.py | 211 + .../site-packages/werkzeug/_reloader.py | 471 + .../werkzeug/datastructures/__init__.py | 64 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3049 bytes .../__pycache__/accept.cpython-311.pyc | Bin 0 -> 18294 bytes .../__pycache__/auth.cpython-311.pyc | Bin 0 -> 15604 bytes .../__pycache__/cache_control.cpython-311.pyc | Bin 0 -> 13404 bytes .../__pycache__/csp.cpython-311.pyc | Bin 0 -> 7205 bytes .../__pycache__/etag.cpython-311.pyc | Bin 0 -> 6095 bytes .../__pycache__/file_storage.cpython-311.pyc | Bin 0 -> 9708 bytes .../__pycache__/headers.cpython-311.pyc | Bin 0 -> 33776 bytes .../__pycache__/mixins.cpython-311.pyc | Bin 0 -> 19194 bytes .../__pycache__/range.cpython-311.pyc | Bin 0 -> 10847 bytes .../__pycache__/structures.cpython-311.pyc | Bin 0 -> 66480 bytes .../werkzeug/datastructures/accept.py | 350 + .../werkzeug/datastructures/auth.py | 317 + .../werkzeug/datastructures/cache_control.py | 273 + .../werkzeug/datastructures/csp.py | 100 + .../werkzeug/datastructures/etag.py | 106 + .../werkzeug/datastructures/file_storage.py | 209 + .../werkzeug/datastructures/headers.py | 662 ++ .../werkzeug/datastructures/mixins.py | 317 + .../werkzeug/datastructures/range.py | 214 + .../werkzeug/datastructures/structures.py | 1239 +++ .../site-packages/werkzeug/debug/__init__.py | 565 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 26066 bytes .../debug/__pycache__/console.cpython-311.pyc | Bin 0 -> 13452 bytes .../debug/__pycache__/repr.cpython-311.pyc | Bin 0 -> 16130 bytes .../debug/__pycache__/tbtools.cpython-311.pyc | Bin 0 -> 18194 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../site-packages/werkzeug/debug/repr.py | 282 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 344 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/style.css | 150 + .../site-packages/werkzeug/debug/tbtools.py | 450 + .../site-packages/werkzeug/exceptions.py | 894 ++ .../site-packages/werkzeug/formparser.py | 430 + .../python3.11/site-packages/werkzeug/http.py | 1405 +++ .../site-packages/werkzeug/local.py | 653 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 193 bytes .../__pycache__/dispatcher.cpython-311.pyc | Bin 0 -> 3477 bytes .../__pycache__/http_proxy.cpython-311.pyc | Bin 0 -> 10962 bytes .../__pycache__/lint.cpython-311.pyc | Bin 0 -> 20923 bytes .../__pycache__/profiler.cpython-311.pyc | Bin 0 -> 7599 bytes .../__pycache__/proxy_fix.cpython-311.pyc | Bin 0 -> 7666 bytes .../__pycache__/shared_data.cpython-311.pyc | Bin 0 -> 13902 bytes .../werkzeug/middleware/dispatcher.py | 81 + .../werkzeug/middleware/http_proxy.py | 236 + .../site-packages/werkzeug/middleware/lint.py | 439 + .../werkzeug/middleware/profiler.py | 155 + .../werkzeug/middleware/proxy_fix.py | 183 + .../werkzeug/middleware/shared_data.py | 283 + .../site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 134 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 5058 bytes .../__pycache__/converters.cpython-311.pyc | Bin 0 -> 12437 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8941 bytes .../routing/__pycache__/map.cpython-311.pyc | Bin 0 -> 41737 bytes .../__pycache__/matcher.cpython-311.pyc | Bin 0 -> 9087 bytes .../routing/__pycache__/rules.cpython-311.pyc | Bin 0 -> 42167 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 152 + .../site-packages/werkzeug/routing/map.py | 951 ++ .../site-packages/werkzeug/routing/matcher.py | 202 + .../site-packages/werkzeug/routing/rules.py | 928 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 189 bytes .../sansio/__pycache__/http.cpython-311.pyc | Bin 0 -> 6105 bytes .../__pycache__/multipart.cpython-311.pyc | Bin 0 -> 15352 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 23438 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 34125 bytes .../sansio/__pycache__/utils.cpython-311.pyc | Bin 0 -> 6859 bytes .../site-packages/werkzeug/sansio/http.py | 170 + .../werkzeug/sansio/multipart.py | 323 + .../site-packages/werkzeug/sansio/request.py | 534 + .../site-packages/werkzeug/sansio/response.py | 763 ++ .../site-packages/werkzeug/sansio/utils.py | 167 + .../site-packages/werkzeug/security.py | 166 + .../site-packages/werkzeug/serving.py | 1125 +++ .../python3.11/site-packages/werkzeug/test.py | 1464 +++ .../site-packages/werkzeug/testapp.py | 194 + .../python3.11/site-packages/werkzeug/urls.py | 203 + .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/utils.py | 691 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 354 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 27577 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 37001 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 831 ++ .../python3.11/site-packages/werkzeug/wsgi.py | 595 ++ .venv/lib64 | 1 + .venv/pyvenv.cfg | 5 + 1807 files changed, 333694 insertions(+) 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/flask 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 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/_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/blinker-1.9.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/METADATA create mode 100644 .venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/RECORD create mode 100644 .venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.11/site-packages/blinker/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/blinker/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/blinker/__pycache__/_utilities.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/blinker/__pycache__/base.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/blinker/_utilities.py create mode 100644 .venv/lib/python3.11/site-packages/blinker/base.py create mode 100644 .venv/lib/python3.11/site-packages/blinker/py.typed create mode 100644 .venv/lib/python3.11/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 .venv/lib/python3.11/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 .venv/lib/python3.11/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 .venv/lib/python3.11/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 .venv/lib/python3.11/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 .venv/lib/python3.11/site-packages/click-8.1.7.dist-info/top_level.txt 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/flask-3.1.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/METADATA create mode 100644 .venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/RECORD create mode 100644 .venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/REQUESTED create mode 100644 .venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/entry_points.txt create mode 100644 .venv/lib/python3.11/site-packages/flask/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/flask/__main__.py create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/__main__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/app.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/blueprints.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/cli.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/config.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/ctx.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/debughelpers.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/globals.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/helpers.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/logging.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/sessions.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/signals.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/templating.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/testing.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/typing.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/views.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/__pycache__/wrappers.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/app.py create mode 100644 .venv/lib/python3.11/site-packages/flask/blueprints.py create mode 100644 .venv/lib/python3.11/site-packages/flask/cli.py create mode 100644 .venv/lib/python3.11/site-packages/flask/config.py create mode 100644 .venv/lib/python3.11/site-packages/flask/ctx.py create mode 100644 .venv/lib/python3.11/site-packages/flask/debughelpers.py create mode 100644 .venv/lib/python3.11/site-packages/flask/globals.py create mode 100644 .venv/lib/python3.11/site-packages/flask/helpers.py create mode 100644 .venv/lib/python3.11/site-packages/flask/json/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/flask/json/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/json/__pycache__/provider.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/json/__pycache__/tag.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/json/provider.py create mode 100644 .venv/lib/python3.11/site-packages/flask/json/tag.py create mode 100644 .venv/lib/python3.11/site-packages/flask/logging.py create mode 100644 .venv/lib/python3.11/site-packages/flask/py.typed create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/README.md create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/__pycache__/app.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/__pycache__/blueprints.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/__pycache__/scaffold.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/app.py create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/blueprints.py create mode 100644 .venv/lib/python3.11/site-packages/flask/sansio/scaffold.py create mode 100644 .venv/lib/python3.11/site-packages/flask/sessions.py create mode 100644 .venv/lib/python3.11/site-packages/flask/signals.py create mode 100644 .venv/lib/python3.11/site-packages/flask/templating.py create mode 100644 .venv/lib/python3.11/site-packages/flask/testing.py create mode 100644 .venv/lib/python3.11/site-packages/flask/typing.py create mode 100644 .venv/lib/python3.11/site-packages/flask/views.py create mode 100644 .venv/lib/python3.11/site-packages/flask/wrappers.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/METADATA create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/RECORD create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/WHEEL create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/_json.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/encoding.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/exc.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/serializer.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/signer.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/timed.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/__pycache__/url_safe.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/_json.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/encoding.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/exc.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/py.typed create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/serializer.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/signer.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/timed.py create mode 100644 .venv/lib/python3.11/site-packages/itsdangerous/url_safe.py create mode 100644 .venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/INSTALLER create mode 100644 .venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/METADATA create mode 100644 .venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/RECORD create mode 100644 .venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/WHEEL create mode 100644 .venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/entry_points.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/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/werkzeug-3.1.3.dist-info/INSTALLER create mode 100644 .venv/lib/python3.11/site-packages/werkzeug-3.1.3.dist-info/LICENSE.txt create mode 100644 .venv/lib/python3.11/site-packages/werkzeug-3.1.3.dist-info/METADATA create mode 100644 .venv/lib/python3.11/site-packages/werkzeug-3.1.3.dist-info/RECORD create mode 100644 .venv/lib/python3.11/site-packages/werkzeug-3.1.3.dist-info/WHEEL create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/_internal.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/_reloader.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/exceptions.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/formparser.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/http.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/local.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/security.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/serving.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/test.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/testapp.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/urls.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/user_agent.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/utils.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/__pycache__/wsgi.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/_internal.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/_reloader.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/range.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/accept.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/auth.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/csp.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/etag.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/headers.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/mixins.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/range.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/datastructures/structures.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/__pycache__/console.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/__pycache__/repr.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/console.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/repr.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/shared/console.png create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/shared/less.png create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/shared/more.png create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/shared/style.css create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/debug/tbtools.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/exceptions.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/formparser.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/http.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/local.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/lint.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/lint.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/profiler.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/middleware/shared_data.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/py.typed create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__pycache__/converters.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__pycache__/map.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__pycache__/matcher.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/__pycache__/rules.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/converters.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/exceptions.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/map.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/matcher.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/routing/rules.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__pycache__/http.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__pycache__/request.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__pycache__/response.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/__pycache__/utils.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/http.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/multipart.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/request.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/response.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/sansio/utils.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/security.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/serving.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/test.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/testapp.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/urls.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/user_agent.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/utils.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wrappers/__init__.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wrappers/__pycache__/request.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wrappers/__pycache__/response.cpython-311.pyc create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wrappers/request.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wrappers/response.py create mode 100644 .venv/lib/python3.11/site-packages/werkzeug/wsgi.py create mode 120000 .venv/lib64 create mode 100644 .venv/pyvenv.cfg 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..e6b8366 --- /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="/opt/createvm-web/.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..6dee331 --- /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 "/opt/createvm-web/.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..be7ba33 --- /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 "/opt/createvm-web/.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/flask b/.venv/bin/flask new file mode 100755 index 0000000..6d306f3 --- /dev/null +++ b/.venv/bin/flask @@ -0,0 +1,8 @@ +#!/opt/createvm-web/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from flask.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..c7dc6d9 --- /dev/null +++ b/.venv/bin/pip @@ -0,0 +1,8 @@ +#!/opt/createvm-web/.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..c7dc6d9 --- /dev/null +++ b/.venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/opt/createvm-web/.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..c7dc6d9 --- /dev/null +++ b/.venv/bin/pip3.11 @@ -0,0 +1,8 @@ +#!/opt/createvm-web/.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/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/_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..5c46e72c729b029b273bd4ad7ff500bacaa8e149 GIT binary patch literal 11154 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 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/blinker-1.9.0.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/LICENSE.txt b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..79c9825 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2010 Jason Kirtland + +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/blinker-1.9.0.dist-info/METADATA b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/METADATA new file mode 100644 index 0000000..6d343f5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.3 +Name: blinker +Version: 1.9.0 +Summary: Fast, simple object-to-object and broadcast signaling +Author: Jason Kirtland +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Source, https://github.com/pallets-eco/blinker/ + +# Blinker + +Blinker provides a fast dispatching system that allows any number of +interested parties to subscribe to events, or "signals". + + +## Pallets Community Ecosystem + +> [!IMPORTANT]\ +> This project is part of the Pallets Community Ecosystem. Pallets is the open +> source organization that maintains Flask; Pallets-Eco enables community +> maintenance of related projects. If you are interested in helping maintain +> this project, please reach out on [the Pallets Discord server][discord]. +> +> [discord]: https://discord.gg/pallets + + +## Example + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +```pycon +>>> from blinker import signal +>>> started = signal('round-started') +>>> def each(round): +... print(f"Round {round}") +... +>>> started.connect(each) + +>>> def round_two(round): +... print("This is round two.") +... +>>> started.connect(round_two, sender=2) + +>>> for round in range(1, 4): +... started.send(round) +... +Round 1! +Round 2! +This is round two. +Round 3! +``` + diff --git a/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/RECORD b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/RECORD new file mode 100644 index 0000000..52d1667 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/RECORD @@ -0,0 +1,12 @@ +blinker-1.9.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.9.0.dist-info/LICENSE.txt,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.9.0.dist-info/METADATA,sha256=uIRiM8wjjbHkCtbCyTvctU37IAZk0kEe5kxAld1dvzA,1633 +blinker-1.9.0.dist-info/RECORD,, +blinker-1.9.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +blinker/__init__.py,sha256=I2EdZqpy4LyjX17Hn1yzJGWCjeLaVaPzsMgHkLfj_cQ,317 +blinker/__pycache__/__init__.cpython-311.pyc,, +blinker/__pycache__/_utilities.cpython-311.pyc,, +blinker/__pycache__/base.cpython-311.pyc,, +blinker/_utilities.py,sha256=0J7eeXXTUx0Ivf8asfpx0ycVkp0Eqfqnj117x2mYX9E,1675 +blinker/base.py,sha256=QpDuvXXcwJF49lUBcH5BiST46Rz9wSG7VW_p7N_027M,19132 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/blinker-1.9.0.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker-1.9.0.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/blinker/__init__.py b/.venv/lib/python3.11/site-packages/blinker/__init__.py new file mode 100644 index 0000000..1772fa4 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker/__init__.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from .base import ANY +from .base import default_namespace +from .base import NamedSignal +from .base import Namespace +from .base import Signal +from .base import signal + +__all__ = [ + "ANY", + "default_namespace", + "NamedSignal", + "Namespace", + "Signal", + "signal", +] diff --git a/.venv/lib/python3.11/site-packages/blinker/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/blinker/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..921b48c453891655e15fe6168c083daa48b83e27 GIT binary patch literal 602 zcmaKoze~eF6vy8+X_BTCaS#M?(W!$C;;Mq1QiM)-x0zSaNtBjLPA1- zceo`xi4|H6+sJlkH{3<;hTVo8WG8eQc9GrCZP-KhLXW@{c<+UTJ?>9n*#9yY4oTf- zN~N0VI90_LzRKjRi}5uM+g#kTnbcIVL=+jj5oY}u13rnTib)K6Cfv+9ziFpfFL3fM z9+^AFTw|WGo-tF4@zAe*N^fU+mJ3RA3v;y{u|oX6uXZVAQd0T`-?#-u+XhyZz1*HumV6 Jo^RpfegIt*nyLT* literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/blinker/__pycache__/_utilities.cpython-311.pyc b/.venv/lib/python3.11/site-packages/blinker/__pycache__/_utilities.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51d944a2c8b7418a1ceea9468292f060f86ee590 GIT binary patch literal 3087 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 MRU%11z|iRb0L5LnbpQYW literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/blinker/_utilities.py b/.venv/lib/python3.11/site-packages/blinker/_utilities.py new file mode 100644 index 0000000..000c902 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker/_utilities.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +import collections.abc as c +import inspect +import typing as t +from weakref import ref +from weakref import WeakMethod + +T = t.TypeVar("T") + + +class Symbol: + """A constant symbol, nicer than ``object()``. Repeated calls return the + same instance. + + >>> Symbol('foo') is Symbol('foo') + True + >>> Symbol('foo') + foo + """ + + symbols: t.ClassVar[dict[str, Symbol]] = {} + + def __new__(cls, name: str) -> Symbol: + if name in cls.symbols: + return cls.symbols[name] + + obj = super().__new__(cls) + cls.symbols[name] = obj + return obj + + def __init__(self, name: str) -> None: + self.name = name + + def __repr__(self) -> str: + return self.name + + def __getnewargs__(self) -> tuple[t.Any, ...]: + return (self.name,) + + +def make_id(obj: object) -> c.Hashable: + """Get a stable identifier for a receiver or sender, to be used as a dict + key or in a set. + """ + if inspect.ismethod(obj): + # The id of a bound method is not stable, but the id of the unbound + # function and instance are. + return id(obj.__func__), id(obj.__self__) + + if isinstance(obj, (str, int)): + # Instances with the same value always compare equal and have the same + # hash, even if the id may change. + return obj + + # Assume other types are not hashable but will always be the same instance. + return id(obj) + + +def make_ref(obj: T, callback: c.Callable[[ref[T]], None] | None = None) -> ref[T]: + if inspect.ismethod(obj): + return WeakMethod(obj, callback) # type: ignore[arg-type, return-value] + + return ref(obj, callback) diff --git a/.venv/lib/python3.11/site-packages/blinker/base.py b/.venv/lib/python3.11/site-packages/blinker/base.py new file mode 100644 index 0000000..d051b94 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/blinker/base.py @@ -0,0 +1,512 @@ +from __future__ import annotations + +import collections.abc as c +import sys +import typing as t +import weakref +from collections import defaultdict +from contextlib import contextmanager +from functools import cached_property +from inspect import iscoroutinefunction + +from ._utilities import make_id +from ._utilities import make_ref +from ._utilities import Symbol + +F = t.TypeVar("F", bound=c.Callable[..., t.Any]) + +ANY = Symbol("ANY") +"""Symbol for "any sender".""" + +ANY_ID = 0 + + +class Signal: + """A notification emitter. + + :param doc: The docstring for the signal. + """ + + ANY = ANY + """An alias for the :data:`~blinker.ANY` sender symbol.""" + + set_class: type[set[t.Any]] = set + """The set class to use for tracking connected receivers and senders. + Python's ``set`` is unordered. If receivers must be dispatched in the order + they were connected, an ordered set implementation can be used. + + .. versionadded:: 1.7 + """ + + @cached_property + def receiver_connected(self) -> Signal: + """Emitted at the end of each :meth:`connect` call. + + The signal sender is the signal instance, and the :meth:`connect` + arguments are passed through: ``receiver``, ``sender``, and ``weak``. + + .. versionadded:: 1.2 + """ + return Signal(doc="Emitted after a receiver connects.") + + @cached_property + def receiver_disconnected(self) -> Signal: + """Emitted at the end of each :meth:`disconnect` call. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: ``receiver`` and ``sender``. + + This signal is emitted **only** when :meth:`disconnect` is called + explicitly. This signal cannot be emitted by an automatic disconnect + when a weakly referenced receiver or sender goes out of scope, as the + instance is no longer be available to be used as the sender for this + signal. + + An alternative approach is available by subscribing to + :attr:`receiver_connected` and setting up a custom weakref cleanup + callback on weak receivers and senders. + + .. versionadded:: 1.2 + """ + return Signal(doc="Emitted after a receiver disconnects.") + + def __init__(self, doc: str | None = None) -> None: + if doc: + self.__doc__ = doc + + self.receivers: dict[ + t.Any, weakref.ref[c.Callable[..., t.Any]] | c.Callable[..., t.Any] + ] = {} + """The map of connected receivers. Useful to quickly check if any + receivers are connected to the signal: ``if s.receivers:``. The + structure and data is not part of the public API, but checking its + boolean value is. + """ + + self.is_muted: bool = False + self._by_receiver: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._by_sender: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._weak_senders: dict[t.Any, weakref.ref[t.Any]] = {} + + def connect(self, receiver: F, sender: t.Any = ANY, weak: bool = True) -> F: + """Connect ``receiver`` to be called when the signal is sent by + ``sender``. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends. + """ + receiver_id = make_id(receiver) + sender_id = ANY_ID if sender is ANY else make_id(sender) + + if weak: + self.receivers[receiver_id] = make_ref( + receiver, self._make_cleanup_receiver(receiver_id) + ) + else: + self.receivers[receiver_id] = receiver + + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + + if sender is not ANY and sender_id not in self._weak_senders: + # store a cleanup for weakref-able senders + try: + self._weak_senders[sender_id] = make_ref( + sender, self._make_cleanup_sender(sender_id) + ) + except TypeError: + pass + + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: + try: + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) + except TypeError: + # TODO no explanation or test for this + self.disconnect(receiver, sender) + raise + + return receiver + + def connect_via(self, sender: t.Any, weak: bool = False) -> c.Callable[[F], F]: + """Connect the decorated function to be called when the signal is sent + by ``sender``. + + The decorated function will be called when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument along + with any extra keyword arguments. + + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends.= + + .. versionadded:: 1.1 + """ + + def decorator(fn: F) -> F: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY + ) -> c.Generator[None, None, None]: + """A context manager that temporarily connects ``receiver`` to the + signal while a ``with`` block executes. When the block exits, the + receiver is disconnected. Useful for tests. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. + + .. versionadded:: 1.1 + """ + self.connect(receiver, sender=sender, weak=False) + + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> c.Generator[None, None, None]: + """A context manager that temporarily disables the signal. No receivers + will be called if the signal is sent, until the ``with`` block exits. + Useful for tests. + """ + self.is_muted = True + + try: + yield None + finally: + self.is_muted = False + + def send( + self, + sender: t.Any | None = None, + /, + *, + _async_wrapper: c.Callable[ + [c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]]], c.Callable[..., t.Any] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Call all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _async_wrapper: Will be called on any receivers that are async + coroutines to turn them into sync callables. For example, could run + the receiver with an event loop. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionchanged:: 1.7 + Added the ``_async_wrapper`` argument. + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if iscoroutinefunction(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function.") + + result = _async_wrapper(receiver)(sender, **kwargs) + else: + result = receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + async def send_async( + self, + sender: t.Any | None = None, + /, + *, + _sync_wrapper: c.Callable[ + [c.Callable[..., t.Any]], c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Await all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _sync_wrapper: Will be called on any receivers that are sync + callables to turn them into async coroutines. For example, + could call the receiver in a thread. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionadded:: 1.7 + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if not iscoroutinefunction(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function.") + + result = await _sync_wrapper(receiver)(sender, **kwargs) + else: + result = await receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + def has_receivers_for(self, sender: t.Any) -> bool: + """Check if there is at least one receiver that will be called with the + given ``sender``. A receiver connected to :data:`ANY` will always be + called, regardless of sender. Does not check if weakly referenced + receivers are still live. See :meth:`receivers_for` for a stronger + search. + + :param sender: Check for receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + if not self.receivers: + return False + + if self._by_sender[ANY_ID]: + return True + + if sender is ANY: + return False + + return make_id(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> c.Generator[c.Callable[..., t.Any], None, None]: + """Yield each receiver to be called for ``sender``, in addition to those + to be called for :data:`ANY`. Weakly referenced receivers that are not + live will be disconnected and skipped. + + :param sender: Yield receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + # TODO: test receivers_for(ANY) + if not self.receivers: + return + + sender_id = make_id(sender) + + if sender_id in self._by_sender: + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] + else: + ids = self._by_sender[ANY_ID].copy() + + for receiver_id in ids: + receiver = self.receivers.get(receiver_id) + + if receiver is None: + continue + + if isinstance(receiver, weakref.ref): + strong = receiver() + + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + + yield strong + else: + yield receiver + + def disconnect(self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY) -> None: + """Disconnect ``receiver`` from being called when the signal is sent by + ``sender``. + + :param receiver: A connected receiver callable. + :param sender: Disconnect from only this sender. By default, disconnect + from all senders. + """ + sender_id: c.Hashable + + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = make_id(sender) + + receiver_id = make_id(receiver) + self._disconnect(receiver_id, sender_id) + + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) + + def _disconnect(self, receiver_id: c.Hashable, sender_id: c.Hashable) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, None) is not None: + for bucket in self._by_sender.values(): + bucket.discard(receiver_id) + + self.receivers.pop(receiver_id, None) + else: + self._by_sender[sender_id].discard(receiver_id) + self._by_receiver[receiver_id].discard(sender_id) + + def _make_cleanup_receiver( + self, receiver_id: c.Hashable + ) -> c.Callable[[weakref.ref[c.Callable[..., t.Any]]], None]: + """Create a callback function to disconnect a weakly referenced + receiver when it is garbage collected. + """ + + def cleanup(ref: weakref.ref[c.Callable[..., t.Any]]) -> None: + # If the interpreter is shutting down, disconnecting can result in a + # weird ignored exception. Don't call it in that case. + if not sys.is_finalizing(): + self._disconnect(receiver_id, ANY_ID) + + return cleanup + + def _make_cleanup_sender( + self, sender_id: c.Hashable + ) -> c.Callable[[weakref.ref[t.Any]], None]: + """Create a callback function to disconnect all receivers for a weakly + referenced sender when it is garbage collected. + """ + assert sender_id != ANY_ID + + def cleanup(ref: weakref.ref[t.Any]) -> None: + self._weak_senders.pop(sender_id, None) + + for receiver_id in self._by_sender.pop(sender_id, ()): + self._by_receiver[receiver_id].discard(sender_id) + + return cleanup + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leaves behind a small amount of bookkeeping + data. Typical workloads using Blinker, for example in most web apps, + Flask, CLI scripts, etc., are not adversely affected by this + bookkeeping. + + With a long-running process performing dynamic signal routing with high + volume, e.g. connecting to function closures, senders are all unique + object instances. Doing all of this over and over may cause memory usage + to grow due to extraneous bookkeeping. (An empty ``set`` for each stale + sender/receiver pair.) + + This method will prune that bookkeeping away, with the caveat that such + pruning is not threadsafe. The risk is that cleanup of a fully + disconnected receiver/sender pair occurs while another thread is + connecting that same pair. If you are in the highly dynamic, unique + receiver/sender situation that has lead you to this method, that failure + mode is perhaps not a big deal for you. + """ + for mapping in (self._by_sender, self._by_receiver): + for ident, bucket in list(mapping.items()): + if not bucket: + mapping.pop(ident, None) + + def _clear_state(self) -> None: + """Disconnect all receivers and senders. Useful for tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +class NamedSignal(Signal): + """A named generic notification emitter. The name is not used by the signal + itself, but matches the key in the :class:`Namespace` that it belongs to. + + :param name: The name of the signal within the namespace. + :param doc: The docstring for the signal. + """ + + def __init__(self, name: str, doc: str | None = None) -> None: + super().__init__(doc) + + #: The name of this signal. + self.name: str = name + + def __repr__(self) -> str: + base = super().__repr__() + return f"{base[:-1]}; {self.name!r}>" # noqa: E702 + + +class Namespace(dict[str, NamedSignal]): + """A dict mapping names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` for the given ``name``, creating it + if required. Repeated calls with the same name return the same signal. + + :param name: The name of the signal. + :param doc: The docstring of the signal. + """ + if name not in self: + self[name] = NamedSignal(name, doc) + + return self[name] + + +class _PNamespaceSignal(t.Protocol): + def __call__(self, name: str, doc: str | None = None) -> NamedSignal: ... + + +default_namespace: Namespace = Namespace() +"""A default :class:`Namespace` for creating named signals. :func:`signal` +creates a :class:`NamedSignal` in this namespace. +""" + +signal: _PNamespaceSignal = default_namespace.signal +"""Return a :class:`NamedSignal` in :data:`default_namespace` with the given +``name``, creating it if required. Repeated calls with the same name return the +same signal. +""" diff --git a/.venv/lib/python3.11/site-packages/blinker/py.typed b/.venv/lib/python3.11/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/LICENSE.rst b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/METADATA b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Chat, https://discord.gg/pallets +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 +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ 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 + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: 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() + +.. code-block:: text + + $ 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 + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Chat: https://discord.gg/pallets diff --git a/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/RECORD b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..fc0b7f5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +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=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/top_level.txt b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click 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..9a1dab0 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +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 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.7" 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..14f534136ac3ef02c84aaff6ed1a11d365ce0b1a GIT binary patch literal 3672 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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..6c8f9f9c5a531e33dafed268c9d94e5223a234a4 GIT binary patch literal 33060 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

;zzEk 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/click/__pycache__/_textwrap.cpython-311.pyc b/.venv/lib/python3.11/site-packages/click/__pycache__/_textwrap.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf81fa57892e4440ee5852c43a47f7983ef5b32e GIT binary patch literal 2633 zcmaJ@TW=dh6rR0$ZEtSQrF9!qH)%pl+n8JmsI90<3nc<2LPbG#5+}~uon6OC zx|SjlB)6*6JXDHNi)8VT7L^CoH^dYFz(y-!?NcO#MBlawNT@GxW_^j1US?;{oSAc( zGiSd!_JfudAAStYuPmH2!{ThwhSo*_yy zp{cgVF9d zB9ql4FSTWg4FELz+@IQm{;5~`M!3l*blWHYL5uJRxTU3%MZBEIi2-a

NoVpO4^ z&H^5W)2nueG9S}$5;m>JyB2D~%kXnz8nRvlvX1^~MLoenck$4-#~vOpcb~GlPvw0( z{x-`Wc96$AR_W|3j#{0A`OB3+&*qJSZ}Wx~=+9rGv$f3|^_kptXX@5e;Zj)+TXMK0 zhbw&p`KiKtW%*di?Ujz8gBb8v)13OfH~L#|wA?#l^^TO~QA-{z)w{!iqN}|NF(O+` zXjs*Zcr$V+hWp{&eGKFy0P+?BgaTh}Ikp+EInG2Y%%0R_)>;sXvr1hZY(d^YUqjwl z@d8#pLt6~s5-x z!`7A}JPAOMWlKI*88}PFzLMMjbvV?2=78XANv?I>4{-K6qNE*&%`c=9T12cO=Qv$q$+FEQ@CsBUFmTbN)8a)TQU{5@3PL5NC0ExD zHDjbnFbGC^2FN<9w6x{fKZAY6@dp>azfkTUxBAD+!82CyjDtjP#3eT;@|QNdD&0Y= zdno_GPFrB}lUvz*wh|0k!RV&ABe&j}xHVDeDfPTw>;eM4EDu@oP|58(ZJl>kZ><&r zH*>dhC8?KCgu<_(q$pZ!NmUfvrzlG)oPpY>*s`Kr&%}~72?OQ#;{+|gxAwJ3Z#)j$E{yF2kKFGma`%rq0?Zr{ zb#~nyEOg#I>3HZ|LV<3_OF18E?{xf>laa60X`vk2Pfj4Q%VB-Oxgv;QcsTOo*`Kg= z@|-){BTqR{-1y2>bq@Q5P?2*G3=gY=%fE}2$JYEqCXtAXso6a+8h}Mf$gjP zPlBHwH$&A7jDct`E6=3!)m*IU&YjzekX literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/click/__pycache__/_winconsole.cpython-311.pyc b/.venv/lib/python3.11/site-packages/click/__pycache__/_winconsole.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96c1edc42e22b8edff90da7fff818a9d1697c515 GIT binary patch literal 13323 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 hJ0Al!h}?hu7xSO){j}#Z*Qfo(17}&>c-tf-2r% z&!dvHcI5CRo2UHaewNCMa9}*Z!ajss##<0>MxLNiC4^fo;Wjhe-eUv>wSB@-y{m>4 zzpW%ojtNN#+?B>d4&l6@wA>YxpxW`7QxLwupC99$jMoZYo7!2!3o~9jcp)`h!|P(a z4)8kFt{Pr9|2Ic-`Rj)bV;5uNS;cb-YcC_X>EM>+1Om<81-2Pu*Nomo1DZ zgSWMg*Qbb=g~+yFQB#aX#B$ShHIq?qWf1hFD&b#=U?L)j`zSG^dPY$-4N;OBpG*^L zBCSouGSP`dQccCCR75qMNl#71QVI{IDusG4#We6Us#f+*Q!qN2NM*`yP0h?`sW?5! zI3xt9lh!qmPlZ|GlS3H`e^$s~=o-go2!CPT>v*k2^Ug>^SH*D`C5;N7A^e5O_zdNK zVU~RvDbOg+v8+=bmh0+t5ZTrbfxIDztX_W*niFj`6Yb^wNcdC~g?k+eO8s1J@s>_CmF4d)45z0v!*NZGWz?Hfdp}aI4G-N^Q#Xf`iEG2tw=QiuIj__WFr2-uzD-5PG=J7ls+_l`#bOP>uO59HLab<_D64|6RBvm zt@WYf$#guH)K3hVsY0lLz6<2P@w+4Bdk*7VjQzZS;lsb&`Cuo%x6*Z_MGKXE2|bb0 zGqF@$Ej#s$R+i{#5mEC~iPWO9)&W{>tE-0Ai+Gy+`fDI}gf+L|Y0o!p{>6>Qy}!I% z7&uiNIEC9%u;b6OKgsfkFOA?@=s8>j4IVBA59d9HSDQQYQl}P1A#wc8!<2CIi24(B zl*;7WxI+=gor+^zQk<%bsX-sZUG@3{yGSR5Ena4}Inw(%a zWp6YZPsVgT8r7*IwX5)4iq@PxrE?d!eh~ z*;@2$&3m?%y0+w`d;T1Ld^}j+hQh2BsG=lJZs5v~O6@-vS^aR?ig@ejZK;U2N*iZ4 z*HqHZ-iF-kqzdl{rC{jZY~Hi!`&38kM-keNnyNIR)iPQ%nhn>~p%PE&wVgz0MwBIz z$hOhoMl@@Oze51+Al_-&csxL`QQFFpG3FHRm6|cJXh~cp(3Z5%P&lLpt$vTHmnIO#-(wWg{ z*%ysYrInc^h5ga!hcmHcg@bNa(s4w4)mxZW@iY{0H)_Tv4SPQ=g4?o~DSO^#iXfIO zJ6?ag>^zmatql_^P?>gdHJOY?G0JJ2vQhpTpMS4Vc|@pS{og?_*Nk6DI-QqJLrAx^ z-+6saa=7{yoofOvOA@4K+nG=>o;2x^Eb11;uTV@J)(y!p*dZ z=Wd{)Ei7q~&&!?wg0P8_t0h!J3Y8@>ZPCoMg`a5)-&GRsZ0yH&LzF>T05_>xDweF( z8hYY7Vs$wN^?*DwkXl+BlI1It30=?9Iv`t5J^yomGUdnQ)689 zI8iN)+MlV(xK(CRnEvbcK>nY!q{FHup>a%&srjvUH_UpZumVFKQ)X5*t4r&nYRg1U zfRvl!9AB56@hK%Dap6YFma+NdrgG4LR{a{P4kS~zjv$#%g<`&Ms9Qr}=vGhZ#Obdl z^MjX``XB8o4vyppN4^=Q_#A$GdXXG%tZ=ZFdI^Q22y=jFb51mnslGqCZoR8E<3>uS zn$xaWJ~@*yCnBu{?A%3*dc#Xp4%?GSyRgF+TNMh<>O_7d*;N?c$oVrtasAv;^KK)y zvOLBU<{X)j5hg`ieWyiJfK>TH&5DMeM9=%V6Hv|Z$ZcN|ih{LlTbne!T$?PK@OR@n zJo4DfYFrbh*u7(AA-nC0c3a;0ab;Z3$scp^F}G8O8kZ;4)JU= z%AkdpR>DlWa%fSReN+dQsw~l}RDL9zQ-M3b{ASlimfC0)^p#6I`W;z3Zao=Xk;aHYB_YO z)cwi>PqBONW97@q;^9mAcit@?zP#oXI!=qv1V=~9b0WD>X!Nd4^RLn`Hwu(ywVJujc)46#Q=#{cj-f z)Z>5Z59C|qf`4n#zjejGYuUf+amUL3(dGT4h5hG>`_JY5y9)mEMgRFyTW6`gYpqH0 z`ko0O&xt^rTZsiI1+;zCzWa$BAaalhEyOtz`T>Ow6OoA=A##)mp&#uS5hmzJs#Flq zaf&2DN%X%5fdn*uYYw-|vnCK}t)L#K>m6Vcq6BE@y0rDt;N$m-gD3gzH;4H3w@_b) z3oi=N0NNmykd2Yz#Ub82^agSK&BK_S>pw+QEu!%X^i%v;|4M{wZkR$%aaF~a;QzS8+`E7!L9Q2Q^{MEMYa>Oe<)HWxT*LfwKQ}Ou1y3fnotDzxt&w2kyF@ zp2^5DnJf%SOj8nBAO<`9Akh$Gdj48Wkr`Sc>ym+Y04@MCCT5cIN0Ta{2QB?kN}kZt zQz({z&^6dmWRwA5g!Q$~N~*#TIhM)9;*)X(xd4v?X7IWJU=a36WaM2`2g3}q2MO_WGa}P5j)W0FaVf1dOD=pO)rS+3`kLUul4k zyqYB8&;iqE*lO3vw4|x@PlKnh8k5Zfm1YPLd1FZibu)>ZDz*9h?1}Fa;)}<0m3Nx` zjoBT#TvO%vj1HJ6-;5;_3d4nDLYYY_fV$JuY6>-ZeS&w;Mzx^<$X+Uu*~!L}LNBDx z#3%R2XcQJ3lamRZdPi;40jxSIjU?FarZ5)d4`3L;L1T0!!81_w4CFlnrOsXeQD3RI zAD3VbKPDV)=38nr)=q;^0(KkFCmuj7u=z13rrx$fu1{p^U1QTSQkd;y2RA@z z{UsZ*u^C|dxGERsEa`#O$Xv?pf*u~G(NS(8P{o8hlO=otnDC6HXEtNQkVB*~MkcP-EVPLQn*;^VITx<5acB}~?t8E=?F1m3GEx~)^ z3tpJE)|x27Beb^N%P#CL1_#!>6yXy(!}l*P==a~|+5LjAWi3D)DySg|`&>SPO}M-S z;mC$wB#ys%1S+BRe?y=#vSH|^h0x6nb6%-dYmH>()LtD%EF4>Dz&IN`#|Jdz zXK1LIp&_5@1{(6S{RAGSok=f4Mn254V7c|J1oUg_`Xv(`J%FHkHTWY1e0_)Ko^k2FL`w@ex#1DxG0EZCXp;OaN+d5R^#WOn<<2G^{0Y zEis+h5SbimgiN9YmTGlYJ^y9b?)Va3fBO&L%MtY1&v_6QApBTKO`aZL=r!)DBrwag(6cX`x1nyR}Af zFKk{sz2scF`uJkObF%0;nfIK0q2@Lb&P8rSvgqnM%^k7o>fc#&J7AC!t=hI$cg~5k zqUJ(3h%mP}V8L@BMySe!ImfKyPRLd#vi{LBlpR$qkCeg<)0k9aCOT-#W15K;Ee0*4 zM7z1juIcBbSxF1bIyLXCQ^ByII%gqO=bS0WtVBjC_AX>P;_u>|btuvYWOuJbvJ05Wp|~5StuZUjxl+fF*3&Spx31jnw&(in{Klpz7`>Y9>E>LsuAc$I8|$wfxsEm zqQ{k;Q~LF?7bFS~4lRZaW1d$hDa7YB-v%OVk?pJ0{F0%GhU`%4QzX)-ForEqYH;Y$ z@Jm6d)t=43Q=J2g*+S=mV&{RJuM|0$?|e1ixnrRhgr85^bH3Hip8HX-vB%%Md9nZD zV1Cb562ajpUoRlEusSAh^=~>T>t1Pe#AGSm-`q>^`4+y%g+* zSt-z83WZ^qY3na_bmcegUi5R_jX}BxjJy;0uE{1pK&gagT0$mG7mjl~@92sj@Asi`&BL?f$<-kBbFu+*5 z3*kM*@E&4)OQj4I!o$Vz@Jjgba`^DqgZc2`Linv>_^sUe)%KozaPPth2+k!ZzvexA z>sK_SK9~ymDFXHtjegWBG1!hnRpzkyj4T4}I6%IcQm4VruBlWgy>VcVw#Ix;ZZp*t z6y_EjXpCW0)!|qP@Ig&h0L%qLL((m_Z`lS0TMkGRV;Rtu?OO#Eu%Uk1_RMzI4cE$c z_%A8>1rUr=+KVUiqFmau@6pA4&ua@E4|*T;E%ZGZ&0Ty-2Gqla(2-*3$V%wMa_Gc2 zgZa>jLg;ES1PkZY)lk>{<9UA{>jEr@=!i5o1ngC;-e8BeF>1ex8frxD;IID=hz+%S z3AGdH75aCTc0@REC+u!Q?$x&T`@IWi?)QCv1aBgGR%i<$`rt-jo}v73ziWsPJubE6 zP0{6&X=@jkmmnPNQv<~DHxJW}`4CZ!(LOwL>g<>{o21KTt#noOt2LFyhWP@!r)k~v zvRz&evu^rq7~Ws@kEJieGW0gv`piz$f_E4c)v0MR{lJiAy7d@1p1J)fX@F=0x?{Uv ze=$5K**#Wn=1|q5CIZ}8mq;cu301G!lU`sx`Uf;K;ZOjU?N+CdI%f}4keFSCK)p!7 z9+tTTtKFemB(YU@0L#{xA1cm9l97~|rOZ+pu7#ipkENMGuF{Z@G8OrvsmKUzxEB|; z&tt*9WLnY^oWGUAEP{z3isenV4WX)zwArhyJ#E6?f2H*AfnWx&wFv%D?j#fc`wHRx z#qj=>@X_V)(I+3|!$%9@i^cFoXal=DlhvlRX&@&RJ>8|vgLLi9v$I|cko0C+;5h;{ zTA<0Q1unyHr?K_QssXHW+>W8_cXnK?I232bn6aqG3rayI}F&cQU(u*QJX2x-v?1QbsJQ zGD+qlaLR11M%`wkL!;ir8i|bwHabXLl-)XnJO}2q#2U=wmrvDg(DX?O2E4*c(!7AElwRg*3NB%1Ei*rkd zio1VU=s!{HKT+sCS?oQT3qEb{E%_rQ|Nf``;Jj39-B$2#FZ#DXYm!2=)fV#ouSaNZ z`^msU^vT<~fr9VNqVLT$7*ASZ+(Ges^1(rzi(UMh_Y86&{VwXVf#S1Us>+_rFjS~; z4dokh^s0@u-*w^;`4{~4uRv_tPa^F{q@A?i4~{_rt~L8zyVnGe)z0oU7u~pp_E1Fw zHqpID=pM%Ewy>L0WDma{JoM$rlSJ|01$MjY z4XnA0v@F9*5dKzF8Qa7(6v}!#IJIu#w2UdYqH#}E%&TmAW&guAw~R6V^0Ujx@w?A2 zwjE=eTt?Yco0pkhhhgHS;WYNS)TpmN=bpseHgFS7q!IZI{`wY>JLYfA;iBHO5#HpK z!PewWh@fNr3P`OiR6M^8(F2EbZ%a3`tGgHuC!hVQmw~tJJqOR{v*i1j-Dc@6nH-|Y zr=FSyTg+)}0b}QNtn48MTXVjFN^x;O)89BKO#k)20jYrG;EO;qz^^6$XUO#h{`_c+ z!LSF5!T5zSAO*N-87+luwRT6VpCI$cw}WEGST-<|`XELA4s2J=0Krv1LNX$jn`aW{ zXFJ-*h%tN#DXg)!U{Z&~VU5sfH=Ed$H~3bJueUMHD?Za5^U*?RM=`X6yr!*=`yB<( zmZE1%-m~SYJp9;GkdGDRV;t{x%h<#X%Hy(h>e0o=`lGkm&DR-r*_gCC z`HmkhQJc4{MvugbfUbUtsKJPW0^)!mqp>$||IRW0}e$;1816*oM- zoA7;*TXAF1dCSsSIQeJq;e~1{Z{1|W2SNn3;KYJmL7QU>eIfua>dYi_h-Sha9#okb z9Z*Yw?+%Npcy?0^M^Tm}WScMx;Tv7}UVypU(d;No?E3@k8q|DgL`<4a>(qEyhZ5L9 zh##iUi1x>bFn00pB5bqg$%x1Xr~yo&(npO?PlHU^vJH}(0RCa9_|Cr*4gy|`7B2ew(HHW$O@C$8y^x=c(+D_jqY+ty{E=wKk zvLWFEgNl#HWj74>7?Bz?5K=pF2_Yd=Zo)SmQ}8@x4y$F?OeT@knX{?Jq;%lQdza2e z&s;cr=8f0K&Qk|yszyr+?#)iiZsz+~c3n-uu}u4rA{a{RrP96TcV_GZ59ag8yabrh zk*&QLN@Kd635Bx%-I-J-F~wCVp9rj}>@(y$&vE|6$_Z^A52DGcKXC}cno|_TlF*(v z&XOSK?Pp1NC2v1hh5o$#ED2qC`&kmUdFS2enhST3c{bACA=1|> zjp_V*&lu;ql|R%kLLSzW`7O^V_IZ^xChnx9^<;kJ8O1)YvaX1yMG^Ma#&mx68RI;+ z@-I62L@a3Q36+l6=T+9I*dhX**OU42XB7Lq%G%}@0R`*HeD)c|KCiOcTj=HL$$Sfy oiI+23+eGmK+PE>zz4?rBo?H1IpNPp?PjbhfQS9>uEH+>N4c+B_FaKU$NuZmXEmA6I-2ht2<58tdd2WB9$u2 zveneIrr}0YTJ2g1JZpBhgJBPPGtR_~@eVSJ46rlk*~I|;CutNAf*1qBEE*W^KTE?I zAjlt!{eAE8DoS!^c8bNXs$RYKz3Y45`RXscUYCI5Z>4vy{qOC9@W1Gxba;z5FaDb- z2=|5W2#TPH5n)2a)e^BxTPLg{rCB4kY1@Py_cp~IaZJ}u)UkUN*M|~+7_YLKHpX!^mR7zCt6sIYlM{!l>o3ttJJGP0&|1ZoQ z)x)qim0MwIk-4TyizXe47j2-JD(APu|Y9kABsie z>aF;6FdDq3YDlTOrp77d8KzgjvlLgg=|Dt{;@+vxM8fevY$l%fjDGvlsWYbo@18$B zelBm*Vsm=lp{em%Ejk>cqNPK^jTQeFO^jZ`!h)C(P7Ck7wP1-?SMNwFBDFQHvW1j#`-ZH!=FW$N{+kB6hzhG%Yn?L2l( zjjFe1wBz&gv>McBH8l_qUX7^3$0D&%FrptHF6Y>S+Vuf|f5C52$oLN8{2;#ieyV4+ zkv~<#7sx3L*5#dQbaqjP^H@qpKrJZzbO_tP2HObt9M70Z<|+K9)|5zZRecuTeu>~^$t-1Qf)ibH@{btL<%b&D9YRz`-&HDFc>-S}(%86kr=4X9>HU@NB55Q>NM!YC* zXS1BI4@blCa4-@GM-??1&o}C`S9SIMS=^VBw#;a%u4*^cz)VmJUekgzQ+kM~p>)sy z(gJz$&luL9d4A^oS^a&;BFHXbT3mpnE*B-5t+D9okdITaC)x9+1F$ z3sOSTy=YgR`5j~}@UAp2c^40u_?cvG$AU8UGk)>IB=!qiJDr$ z$9}j`o39BAuBCePYv~6V#bxh;dqKd6k~~>=DAJOb2;1DB1K^wqw>Fq?ZPF4)x{BLZ zkk-zR8LKEncf17SH=6NUjEbFpW~qdF+Ii`@(>s)CB;xo{+6ZYRSs6^ts?wdwK>G&dYYp{uv$ z_*_g@r)T1~fbbR&&V}PsGSV1E zhKR7rq&fw`k)qeAZ}OEZKe&43iX55(-w9Dib|B@}o3`sO5 zYbuTT4584cVzUti4VsxzqsYxi`6|TgjbiJMPz$Hom>yv@(oFGe#lmQG5u>UMvpR}p z82jXfAX~%Jv(xAl!k*;ig|%e>t`L`px$DV8VpU*-05m)HXgpIvX+=?-+(}ma0&)( zPDX;)h(>jlMgUVqb6=iCqSil9zig)FA_-Q=Pv>pXNN7PKyT>uh?-G@$+9*WxD@fLM z0OXrAm5q5|ZVDn&ClS0Lw}$yhf=p$ zU1nVCaicZ({nYY0AULJOHSw=SY5Z%^#m0a1Yf*-3Z6}JG$vfEERPwg#u`slxy!Gnr zWZqHKMZ_7VCM_;5ay7{nn2gNoQ>2E>cM*LA7-KE#%azxo7(u3qeg##up@|gDEjdq9 zax~|zPrko$@b0nYV@tFL3iHCIzzqEcH(W`1=|1&876_Aw@qRVw?+Eqsj()x1T!340(or|qW#2M8Pl(8+mF%@^Ky{74DxhQW-Cbj ztFJI6g?)nkm5gnm`do82+&!^;BJ1un+?|W3bM8#&3F+qym1zBAV$7o7G6$8!PT zO9G2$3m(DKO&W1;uA${_VmXmIoo(nb8hSEP&)VS5#gnnR9Mdlv&qTaIiQ$=Q|jv?MPqU0k`CyqIflqZwUmXiom|(~iFM z>7O5eaC}wDZSA=KqYr=d!NR?TRa>sD=f9kLIR2}#Uyo(m_N_WV4RX);q7_ig$ec0@vB`~ z?{34pyCB${$Opj4-0B_9`I_!KKXj&E`J#R3N&C=4CEGq?w2x$c`widz3_I6KS^jL- zFLtHl+4fyV`>w2S$nXtid_x6i2_?h(oREK6uBK99%^fDTCWSqIMbp%D_vrG`Rc-0S z%887vT_@i8KlhyUpYhrM(Pum3cmCs65pW%kMKfqs#6neHPF8FesN)Pj8xp4L1+3ggRUZoy+ z8u0g-FiKT*ag2??=z$NagmDWnc!9}}Yd!o?rSuj&H&8E>KBW~neZ2K(zx_Jd*6dIv zRjT$jRn^vpez)V#YwbX-P3jht9 zQ=lT$IFr^?rDJZOTgoyU=b}jg8-hBC?!dViMim?AOdJU&W_kvLg8V_bq`Shhc2c1#7~x zcrsp9n!GKGhpJtS)sDl2Elt|ny2DJ;6;_b2noU2&N+z^oGpACWXj|E+hPOuul+EF5 za9jk+<}6ca>|CLF_D5)lM*gB_Bzy;5aHUN_^^Iuf=>=iXngQT<3rF*f@Vh~}^Jxj_ z;dwP*2UpbWbX4bKS|6I#G*C%NdOM&6O~Q3-&)al0GRct+5Yh_-$d^;=j*|i?3`cTc zzQwd2hfC=i6}klg@#_(sE%1lnwOAs>1oAIi!{3_9QZ?fGoyn9(_wdHYhf^HOH~oows7M(ew)_FQv&(zfEt zZR;ky9l5^kcyuT6<32bCw=_%+I3gKFHb-zne%b4|@?&G2I3b$#P>Otj7g^@_zRTBT zP@av3Lor1yT0(rG(&`}dobe1k#KU8Q7VR?XVoDV5$LanZ0G(Dr$=PXV>wSKUd1zVU zPbn{XKNp2H$+P1ALTY~^wWkhdrCvko&6G~o`*j{^)@xD*sn@r}O207%4cB_Zkhfz?>BdbmtR7r7v!a6 zy~#)&n8Q@u=-!`|_VXt|od2HgAk?x^cTTIDc1N3_&U_!Bsuy_&gaQ^#ZAWkI1X{LiM*1=Lm=Wt@Q?=_?sfnlj5)rwNh>^iI ztDdi43Lja138u&1Bi4dJv%K1lKE#Y|NF#A|*S5@@ZX4q=m$$Y%kV_EDkSZ-Y{R`jA2@kFlb5i#|y#%?t; zZbhPT`8W31@rQf7S${X^1#ukb{Qs$N934sw_rWl=fVfSO$#6}A?4+XehzOCZ1awC( zsAzCn<>I$08&T>Jx#Ej}hlCtf2-%<>C`J(4$N~pql++a}NJqI2^0gg-l2G!ym0eR6 zchRtXntLQkeJEofELX1deusK=MDD$ErGk8H-ocZZ4g0lt{2A$+V4M}3ayJs55iKAD zB?dSnV#15m1MRy6&JZ90IatRzE^#;Q3V|R%-ZM*82lyJzyU5Hh>KtTx>LjnJjX1cq z>1M1rz)H=xnHgKvD~e6&XTS&{1N|^dlES0^`k@S zi`kC7M#tW4^Imu#JU+7ip8DEy{??p-Tdr?+ZeSNI+r}nXwvA1&Y;k9;^VWYU0Kj4` z0l(mFWQJoR>*+T<{TWYx5m}WfnL~xA(l$dL`J3;4KAAmm#yD^$+c|1e>3M?$2V+ParXJ1@`@|gToLZY<;J+Z7D9dVmLo2b z@Qmn4B9%wA<=d=u z+>nlEO6N;N=bJ!k)_=6E7`w72fY;>%v3aC_T7Cx|$a0ze2d(pcgC-sG!Qyyp>JZnX$h@LZLhYazZ8jcKfT0>y%1pQ9B1f#I9A>TXUB+(5tDV){ zcgH8u#<^^Tw-UcaW~R;3$TF4B9CUW^$)#q_w{A4A^yYt{tgZlnV@g6(^J?7K`f9fE z)ubaQd5H9%dYW@SKhAruT=(`|?~Yvmj)L3at$!{6d`aNBRdTw%g!9Zr9yC{>>7@+i z8R^n|BLW#o0ou6WrW^9c6Q8l+ed#D`Y@cC^wN#{gu1K8rle2S))goFp?Dxabas9u?98DcGANm6 zXF-aW_mg3C>JpOTeB}BVH1uhi6Jck7Gfg{Y)*T-srLy;F!If}nmpAKg!c|RWus9qW z%&bdsE1v2I5q1FVSa5HKlTppOu_@Ayo7GXHnoyV$t1;*Evm`1 z>*k0YEGyI$=Z0?&L1Ee=h2Ug4oU2VUhArO=MrPrytVL90R$Q$wxz)JGjl%ZO!nxYb zJwF>3FS0m}0(-ZvBIJ#-EDot7ejcAwi_uYzs#<(d|7#D#V`FSc$k$YV4LYGIu+9!m^gYyi(!0Fpr$}Me=rb3-=rA zsy0QhJv@}9u!vgT&Ld_g@kXchRy|1EdXTszR3f#$vr_sKDr*M=Uljhe6PvMCPcO}{ z%qMM68@Hw6*~WgOu|Mf}iqPWCrK2lHQ$0`I9T|7W)25D0=V-R+tkHBf<2n0#|JIZv z_5K5A`n9Zor{UlE@J7~uIO+U-*FZY{o6C<|KKcHm?`OLX8(oJBLbJ2yIf12bCC{uL zEb36H-ptlxKKWoOb%K6b-%i7~ zGvnL2*4dNpN%y9EADo9K*?5_D6aucEhIw`W!iN{qy_xQ})3+b*H%3OYuZ-e>pTF~$ zZ?pbOhW}EAozJZdhl7HE=CQ*d7ItDf*u-$V$3_;rNns_$q!0fW{{m3jN0`R_`oqlP znUG?lvNmU}62o$W4%Z*G7!h0&`F=z&<+9MJE>~NE+=_iwW89l;!Mb7%^UY?pxS0HZ zDLO4|%+TSnRj<+$hvhS4k=lAMubQkdP#?j`RE{O$#d)!Cl& zG$zl`Zw)rmTgz`PeQV`gN%s3HdAd3Qu~o*p{z0^z>=6E;qvhmYtI3yKCcXcRX8qep z&qOF265*zV@{Mv=5z5|^8CG}#vGOBYn=nQxXFR}ylcHaRqk*v+NqCL=F36$ z$G>AHNFt?d`-H!4IVqW^fmROvUyyfzOx856>kp`r<)JgHn^1@>^PQL2o`3Gv=PnIC zZnQ3#9LA`O04)z()Eey)qD@Risg-7>^cEVA7L-)H}SA(s2#GGgi1_F6kATS+MW+Qa(2?X9p@V5A-E)Y;+ zAtYO&%H_p)Uivmu+JX`7J3y7ULRaA0KxLl8R0mtDY}L+CKIt;slpIp?_Hk0ov<1pU zgPoVoBcv0IL%&$0w4V^TLx8-@+_^wDhIY0DCUK)5VB&lcgFwH6#c7vltA|u*7kYYg zJ==5J2Mf+d`#?beSZnVp*y#aVu^U(BQ++ExF4WPpB>0=}9Z7}mo#2^Wf~&sZE)`>C zIT*0m`%WuuCnFEcOGGRt+{va|x%#b7H|dV27j!$oaRjhg^3rzwX`lS^MXw zKI>*rYff*$UdqbybMQx^#eO1vnJPT-aGYIgfn=rKFJ|DXx3{JAf`Cgp&MviJKxl2x zb#xY-ui7Cl0oLjpR<5TSA8bu;Nr%#{M%$}K{mz1&UOV7XDAduNB(${gB76i(g&778 zzAFk2f5GChx6?S{l0NzC3lHN)|9o`!q86?@6#E?kF(I`3Q~db>zhYh5 zR(h(wVh0Vr-+B4hI0?%nypn^?pc@F!VrwXEYc9nu_~;cww8ZWp$7vrR<9yTboiUAI zI;LaW#S8)^Gg=t252i9;69%*P_~%jP0%YtVe6gc!^aXg#nJXK?=;yq5CW^fy+|n!djK?ov zM9%SDxl|cfOGcSd^|iQr+(bL1+L6EEMH2vdf~)tFl5pVL4;W{I-PM3xI?WUhgM2L= z!`6P@7|=br4OWr zsI^pc@$)DDK*m3i3a-Ar`u@Ff+}502fY~*2d$F*-){8rArNGBdd@rP3TcvlWD0#~U z1d+F5lL=h0BBOd+psB+t#&)7Gg4x9{~9Dsj)pZ^1-%y z+tQ-Z*qd~$xf@q6FTb9AJ=Z&s@pP|AuDi}<=bw(O-u&R`y`yPsrl~(GZ8xOt8FsGO z96vkzle4S!tM!X#v$k%-hB~@)*fV)}`7rN)dLOP?|9}DL9x&VknH@(n?xPvoQ9d9x zt)DvGQv#!dZFxuhHtm$xmXVlu74>&~%Ekn%Myp;UVVSRktvx*xEPg%afP)$z1n~hT z7p(Rl2rN;~hCm<~jmF|kDbpeMxpc;NZQ6gLOe+MKbKoxB^-&qy)mSXTV}eXZv)DZi zX^jL2eRD12xc29Gi-8yPe*#1(K@@XBQ>N<73EMN~GbhLy^SLH;Wz1*J{D`-ZQ9aui zJ;@+s*p`)8M(D?x75WQ~I`OrX_`sFk`|H;pjy$$LJY@9kH(DXR@#6EI|NhEv`+lqc zc877~EtXOX{5EkU=W?&Sy88CLcT<#z(m4cPt?0=12*X)iv6RYCAx|B6_ zIVE9Fs$uUf*pUOVITL6Sn*6!;&Rkb_PTpQ{kBVYPK_HlOc?(v$S##GH>@3|OG`AM& z*sUbAb`+fK)+MxWD;D$!4rjs3QW*}8sR%DwG>ZuFxG{Xr(!Z>Jd)?k79!vE+cr|_b d0XD4S;bHL6wa1~)_dgCB!*8&ZO#!3b{|5jXD}n$3 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/click/__pycache__/globals.cpython-311.pyc b/.venv/lib/python3.11/site-packages/click/__pycache__/globals.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c3980a00feb9df152dadaf0830bd714e96feedc GIT binary patch literal 3360 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 H+u{EQkUWnv 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..8f0148f5b1925cdc1c37b143a58a11079f0f97e7 GIT binary patch literal 23971 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 bgalowS{=BB2k_<2IDdSk^2eqLi--Rk8a;YL literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/click/__pycache__/testing.cpython-311.pyc b/.venv/lib/python3.11/site-packages/click/__pycache__/testing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c219dbf90e32d894b1f960dd1db2d9237fa75948 GIT binary patch literal 25755 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 rzA{`A5K`itp!)!i*fE_H2@#+KnIxDCP!Ebs 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≪4_iKRr#JU! zyN+jDp9U`(QPR(z7M>EW^B3RjAUP|Stro|g`4LJFOj*@=U_;QWU*-rkQH-dw*I%DR8lz&6 zaV0Pc^>EG-%C5s?^Qt*3O{_ACi4hx(p{oHP+-C|eAPHuH?aW$D<(G`*H|Gs|fFuJ_ zuENt6uniY^tJjQVJj%Bq9rOYzDkTj<_bFgS=$o>nw(V6CajMl6S%s-Asi_7i;WQ7G z3o1@!$$Irk3D-o!%JMs|97 z>wzR$Mj^5r91pM-z{!Ti6WW0hhTRhsH4@TPoJHpArmbB)IKWm$)nz&tSpGiwzDExA zlbGKOhZ*`_p?3^(|4;J$CvyHXIfu!qLIU}6?8ulp%iBcql?M_q_(66%j*txw`TwC< zXW)Q2%M15a`oeo|DvEd!Mq=`ICgBO~!V(@5z{;A{BT4NiKnRkh!1Xni~J?zW}CcfWDt8<~cU*@lht2j>rd($KOH`EKKl#`%Mv zeNu%y-e|erk~(<5t|{gHq^xSb?K{y-S#!3mnV@mQJ(y}g`P!9hS70wfgvK&up==qX zoE98l;j6-;T;~3bQ*&45t|0Z}_h19DLVI)1SDh-Sr!#X`=dL2Hl$V}P&rQ!w-}BX^ zJon3LD4|;ZY}xK|R4rS}+*S8{4GV2=$1=WkS>HNT27=MrcC7Osx1|HmiXV)y)zP-( zI!Gqz#Y>hQ7yj}TWP0(MMSXFSbWPjlMd%tqRN7F>6D zuk^FMa8R?Fz>_&hibfFrPDefQ@;x7HlarOG921I4q1y# z3{Kfaub_TTTsGR&BbU<)#}sV#Bv|+@HmK7sseHxh7oR;cbm*xgho0^qIF_#xISt{A zpXdbd2m&hwRuFNrK~yFv#|nRWzexgtJcQhW2RI43cyP++$u~*PRdRkr&c7t*XXN}P zISpCza3fUrwq{tG}Gok~aTxQYdZy z<)r4c`FCGhn>PPSebt_pOuwAemNx%#Qd8ReD}Hm|W`A`b&VaUT&e_}2>Mv(+Nt=H; z`>M40m$Pq5n}5sBgH{X1cxm?mzyH)2dfe`?v_l7>$XS4~YrOqb5Ap{sT{vXA$eHhd zKyN?QgEqM>Er2>j&O+}4di$v!R9|Po@z=%9eCz?e{ZtRycHUxv`Q*}W>cs~f@~JWW zdD~%&1quD-ry47928B>_9=YUajXnRs<#&V~nfU8*wUs?WOW=Nx!+1?Og8`Npf?n6qQ4 WcQvHT>N91H*|NqtJN+@0^8W(-$%VxL 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..f590ae2d2c42811e7e6bd174ab694c0a9d131a6e GIT binary patch literal 27966 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 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..23f8866 --- /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( # noqa: F811 + 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..f744657 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/_termui_impl.py @@ -0,0 +1,739 @@ +""" +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 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: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + 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, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + 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 + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + 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: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +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 os.system(f"which {editor} >/dev/null 2>&1") == 0: + 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.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + 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 tty + import termios + + @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..cc65e89 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/core.py @@ -0,0 +1,3042 @@ +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 .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"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + 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, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __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 # noqa: B902 + ) -> 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, info_name=info_name, parent=parent, **extra # type: ignore + ) + + 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.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.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + 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 + + 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("Could not determine name for option") + + 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 self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not 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("Could not determine name for argument") + 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..d9bba95 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/decorators.py @@ -0,0 +1,561 @@ +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 # type: ignore[return-value] + + +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 # type: ignore[return-value] + + +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 # type: ignore + 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) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + 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["callback"] = callback + 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..fe68a36 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/exceptions.py @@ -0,0 +1,288 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +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) + 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) + + +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..480058f --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/globals.py @@ -0,0 +1,68 @@ +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..5fa7adf --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +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..dc9e00b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/shell_completion.py @@ -0,0 +1,596 @@ +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 subprocess + + output = subprocess.run( + ["bash", "-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..db7a4b2 --- /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) # noqa: B306 + 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..e0df0d2 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +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 + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + 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 + 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: # noqa: B014 + 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..2b1d179 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/click/types.py @@ -0,0 +1,1089 @@ +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. + + Starting with Click 2.0, 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. + """ + + 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: # noqa: B014 + 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}' 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..d536434 --- /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: # noqa: E402 + 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) # 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: 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 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/flask-3.1.0.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/LICENSE.txt b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask-3.1.0.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/flask-3.1.0.dist-info/METADATA b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/METADATA new file mode 100644 index 0000000..c49ceb9 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/METADATA @@ -0,0 +1,81 @@ +Metadata-Version: 2.3 +Name: Flask +Version: 3.1.0 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +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 :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Typing :: Typed +Requires-Dist: Werkzeug>=3.1 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.9 +Requires-Dist: importlib-metadata>=3.6; python_version < '3.10' +Requires-Dist: asgiref>=3.2 ; extra == "async" +Requires-Dist: python-dotenv ; extra == "dotenv" +Project-URL: Changes, https://flask.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://flask.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/flask/ +Provides-Extra: async +Provides-Extra: dotenv + +# Flask + +Flask is a lightweight [WSGI][] web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around [Werkzeug][] +and [Jinja][], and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + +[WSGI]: https://wsgi.readthedocs.io/ +[Werkzeug]: https://werkzeug.palletsprojects.com/ +[Jinja]: https://jinja.palletsprojects.com/ + + +## A Simple Example + +```python +# save this as app.py +from flask import Flask + +app = Flask(__name__) + +@app.route("/") +def hello(): + return "Hello, World!" +``` + +``` +$ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +``` + + +## Donate + +The Pallets organization develops and supports Flask and the libraries +it uses. 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/flask-3.1.0.dist-info/RECORD b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/RECORD new file mode 100644 index 0000000..0d45a27 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=BZOmndXD1foIDuqbtpgc1qxO7muhcA8DxLB2bL0Obi4,227 +flask-3.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.1.0.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.1.0.dist-info/METADATA,sha256=Wvf66xwUclGRu89cNcvErpaMf1rMgcxeqIkTc4EmD90,2718 +flask-3.1.0.dist-info/RECORD,, +flask-3.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.1.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +flask-3.1.0.dist-info/entry_points.txt,sha256=bBP7hTOS5fz9zLtC7sPofBZAlMkEvBxu7KqS6l5lvc4,40 +flask/__init__.py,sha256=6xMqdVA0FIQ2U1KVaGX3lzNCdXPzoHPaa0hvQCNcfSk,2625 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-311.pyc,, +flask/__pycache__/__main__.cpython-311.pyc,, +flask/__pycache__/app.cpython-311.pyc,, +flask/__pycache__/blueprints.cpython-311.pyc,, +flask/__pycache__/cli.cpython-311.pyc,, +flask/__pycache__/config.cpython-311.pyc,, +flask/__pycache__/ctx.cpython-311.pyc,, +flask/__pycache__/debughelpers.cpython-311.pyc,, +flask/__pycache__/globals.cpython-311.pyc,, +flask/__pycache__/helpers.cpython-311.pyc,, +flask/__pycache__/logging.cpython-311.pyc,, +flask/__pycache__/sessions.cpython-311.pyc,, +flask/__pycache__/signals.cpython-311.pyc,, +flask/__pycache__/templating.cpython-311.pyc,, +flask/__pycache__/testing.cpython-311.pyc,, +flask/__pycache__/typing.cpython-311.pyc,, +flask/__pycache__/views.cpython-311.pyc,, +flask/__pycache__/wrappers.cpython-311.pyc,, +flask/app.py,sha256=GE7QOE_N9THDjuzKx0gUI9aF4hLh0xwBDa7hLVsjy-o,61725 +flask/blueprints.py,sha256=p5QE2lY18GItbdr_RKRpZ8Do17g0PvQGIgZkSUDhX2k,4541 +flask/cli.py,sha256=XdmkBD74SnT0jrt2gqyHrE9oXGdWlcdTrJQR-i5aApY,37093 +flask/config.py,sha256=PiqF0DPam6HW0FH4CH1hpXTBe30NSzjPEOwrz1b6kt0,13219 +flask/ctx.py,sha256=4atDhJJ_cpV1VMq4qsfU4E_61M1oN93jlS2H9gjrl58,15120 +flask/debughelpers.py,sha256=PGIDhStW_efRjpaa3zHIpo-htStJOR41Ip3OJWPYBwo,6080 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=7njmzkFJvrPSQudsgONsgQzaGrGppeBINevKgWescPk,23521 +flask/json/__init__.py,sha256=hLNR898paqoefdeAhraa5wyJy-bmRB2k2dV4EgVy2Z8,5602 +flask/json/__pycache__/__init__.cpython-311.pyc,, +flask/json/__pycache__/provider.cpython-311.pyc,, +flask/json/__pycache__/tag.cpython-311.pyc,, +flask/json/provider.py,sha256=5imEzY5HjV2HoUVrQbJLqXCzMNpZXfD0Y1XqdLV2XBA,7672 +flask/json/tag.py,sha256=DhaNwuIOhdt2R74oOC9Y4Z8ZprxFYiRb5dUP5byyINw,9281 +flask/logging.py,sha256=8sM3WMTubi1cBb2c_lPkWpN0J8dMAqrgKRYLLi1dCVI,2377 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228 +flask/sansio/__pycache__/app.cpython-311.pyc,, +flask/sansio/__pycache__/blueprints.cpython-311.pyc,, +flask/sansio/__pycache__/scaffold.cpython-311.pyc,, +flask/sansio/app.py,sha256=Wj9NVGtiR1jvkZ9gSFd91usUlM8H0g06aPVz2sMh4bw,38116 +flask/sansio/blueprints.py,sha256=Tqe-7EkZ-tbWchm8iDoCfD848f0_3nLv6NNjeIPvHwM,24637 +flask/sansio/scaffold.py,sha256=q6wM4Y4aYMGGN_Litsj3PYKpBS3Zvut0xhDmpBEHFdo,30387 +flask/sessions.py,sha256=pImSFQIDCPtV-XSI8ttAyTTbvtRMkhDeqJ8VPZZUaf0,15430 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=2TcXLT85Asflm2W9WOSFxKCmYn5e49w_Jkg9-NaaJWo,7537 +flask/testing.py,sha256=5Dxg6VZ0ZPhjwG9ReUl4TrhvkjBYvgIzV949jkY0jIU,10100 +flask/typing.py,sha256=b7mMBIeAoOcAI_vFzzhfOm7KeZ_n868SIMw6xpX5KYQ,3166 +flask/views.py,sha256=xzJx6oJqGElThtEghZN7ZQGMw5TDFyuRxUkecwRuAoA,6962 +flask/wrappers.py,sha256=jUkv4mVek2Iq4hwxd4RvqrIMb69Bv0PElDgWLmd5ORo,9406 diff --git a/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/REQUESTED b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask-3.1.0.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/flask-3.1.0.dist-info/entry_points.txt b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask-3.1.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/.venv/lib/python3.11/site-packages/flask/__init__.py b/.venv/lib/python3.11/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import typing as t + +from . import json as json +from .app import Flask as Flask +from .blueprints import Blueprint as Blueprint +from .config import Config as Config +from .ctx import after_this_request as after_this_request +from .ctx import copy_current_request_context as copy_current_request_context +from .ctx import has_app_context as has_app_context +from .ctx import has_request_context as has_request_context +from .globals import current_app as current_app +from .globals import g as g +from .globals import request as request +from .globals import session as session +from .helpers import abort as abort +from .helpers import flash as flash +from .helpers import get_flashed_messages as get_flashed_messages +from .helpers import get_template_attribute as get_template_attribute +from .helpers import make_response as make_response +from .helpers import redirect as redirect +from .helpers import send_file as send_file +from .helpers import send_from_directory as send_from_directory +from .helpers import stream_with_context as stream_with_context +from .helpers import url_for as url_for +from .json import jsonify as jsonify +from .signals import appcontext_popped as appcontext_popped +from .signals import appcontext_pushed as appcontext_pushed +from .signals import appcontext_tearing_down as appcontext_tearing_down +from .signals import before_render_template as before_render_template +from .signals import got_request_exception as got_request_exception +from .signals import message_flashed as message_flashed +from .signals import request_finished as request_finished +from .signals import request_started as request_started +from .signals import request_tearing_down as request_tearing_down +from .signals import template_rendered as template_rendered +from .templating import render_template as render_template +from .templating import render_template_string as render_template_string +from .templating import stream_template as stream_template +from .templating import stream_template_string as stream_template_string +from .wrappers import Request as Request +from .wrappers import Response as Response + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Flask 3.1. Use feature detection or" + " 'importlib.metadata.version(\"flask\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("flask") + + raise AttributeError(name) diff --git a/.venv/lib/python3.11/site-packages/flask/__main__.py b/.venv/lib/python3.11/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8137308f044e6867d122cd570efcb20ec5fd5c71 GIT binary patch literal 3165 zcmZ{mNpBoQ6vwM)>sc}$?|ba_l8nbmX5xfJYzYPuxR65vLaIxvJzZlr?v3giJ4T6w z5C_DC0|z+f6qfJ__!J!!iB_K?Ar8421vuma@0F)xx5spz|MTlt)m5)vy(;DVYPC$@ z`K9>L<~q>t_>w%C15lp+qY&~fF^Q?z#8IfCAZP3h&6-&=XXl(e&4Vv%=Iw%`QdM%n zE;=PzlC0Wgr$Q@|i}op}N~@AfzyowZav8WrYmzI#gLF{xDSOBnro)n}z$0`-@&NEC z9hF=I9;0KD2kmiZf=);t0-mIkl81q(=#=CU;AuK7c@%ht&PW~uo~5&r$AM4N(~>8E z=jfc|N#J=pFL?@BqnhMtJMS#e1<5n^qO(MoB+mjb(`Cu0fzQx0lIMWW(zBB1f$Ov` zSp#07E0Pz08?+&L5qOoZN?rm!N6$%K20l;EOFm;?aGJC!`7CgYwj|eqFVc&WSAf^( zn&gIk$+=7~OI`(jfxZBI(QJK@qc577Tcok}1dE`d#1+GJJz)sTbAuaCpdiqh`#A7i z_|0FpjbIy~^p@RaKDS%}FNL=~w_|Mr4I3T7xGuJ=KSBxvh6R4n0&%tkuEJL$Ib^PITY%eP$ka zc7rYHoH)``FavgBQ#ZX`T=w_|gMl$<*TjwJEel%4Hoe2#v)gUv;}%0ht(S`=H{cpf zGT*UWt2b#a@dd)*LdG$gxQ+!eluX+TLw1JmkB2mV%%umAdl&b#284-A1_IakG1p;d z_2%}?)C1;1Gb;**9y9lI{yvQO0R9dhh1^j-&Lwa6aK^sJEZm2v z9z2ii77^9MPIpMU^>d}6-iRx@zQZ_HyRLJL?9*>P*kW4!h`X*muV&2(G!qUiYeSKn zn&Fz-u4UWW2GclmydCgat|m{ncDcFM)IJQD)?o%Dj=_flY940NJg(I($A^<;TN_P> z3Bxpm(d-4XvWUlPd$Cc6!2&1>v-t!ggWW4b)wH*5w!`d$6S>_`)38 z+E8PH?Kl^9*+vT%;qJ6xSuKB0Y);5A}z&OOI-o!s4Yr%9G!XJ}l2YD$j+v zxu-BIY2@U>`2}E(!SEJ(Uy94R-s$3QLZFz1xFGg?$aAcSm~gDhI1ASb$6Aid8_De+ za8-7OiwSOcUX=aX;x;bEevum>}{06+@Q4Riu;@;0HiV~5< zFl~>?aG2O*G99KZBJ*L|BGL@g7LnyJZ4r4TOj|_W57QQr%VF9g@>-a-h_u4AMPw#S zTSV$%+D`H;g(PKB`W0FuvL2=_BG(rFBySCnvAztauYN2{4|+vF(>C_7BK?_S2BDCss81rpI=a-pInrhSdvC4B zUaz3?7l%!5eoARhs$CHW&{&YQ#UO`%U}j`wyul!P0Tn%9U}<1!WNTq-0K+0Spi%%r C+B}E= literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/app.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/app.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5dc7a4f543d34e427362f79d7fda9af30e9656a GIT binary patch literal 65068 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 bv`>-_fpZN8)&G_8`s^1f3lG}tqa6Ivr(%Hv5 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 v*yw*+Oi=y$Sbu6`H$b@#j3uczO`e!cx(_Ur5S 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 Cr7gGs literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/config.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6103219c1e8a1b514ebfa6bd0c6f1994d369ab99 GIT binary patch literal 17212 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 X3n7_Ka_6t|*w>==kKfRU5BUE8y*$Sz literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/ctx.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/ctx.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24ad56fb0fc35fae1fc89c3ee14571a3159f1604 GIT binary patch literal 20895 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 B-iQDI literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/debughelpers.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/debughelpers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c371864ab003a0d1f20252772d68e3f81b75db10 GIT binary patch literal 10206 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 R3j(JeY&nE@Zvga2|33@m&5!^9 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/globals.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/globals.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..920d8184da7f16134b70e56d8b1f7d5adf7fd791 GIT binary patch literal 2217 zcmb_c&u^RO3+u#7n5GW#{*g_STinOXC3Mnm$no!h5XtnW7oF%(E?(D1+ z=afSaJ?2)9IZ>+i(jNO)I1&eIdqLvFEfqb{OW)hIiCxUCtGBanX1?#uoA1rePx*Y7 z!1G7uLF2a+AuqAhf0B`-z5ZPz^oh{V*^|zc zJ_Y`mJ{==G$?{Jjr(fWW9=*uMd5INnLKo)KyvV12op>4p47@!|nN0#_>IB24LsT44 z@b*xrSrJgB0aSSe>I^##s4}A18NCwbRQXR%Gi(MhXWvGe;gxrCI?K)h=KKkU&4#Gq zoX)X1K+O)I=m^w#b^%Z{%qg};7Uo~!mKL-iXS%LXrm}?V-GhF1S-6Vts&7n*y)Q-G zv{$9rZNEZ6VJP{zZF<|_j2oXdo6BnVwkU*4S`feS!X4;l&M>v;r##vTvaa#AKFnJC@qQi7LECFUuP(+djl@I=o?LE5Od3|IzqEBNk)@Lgs&pr_g3@)VRNNQXJ7-5?H*Oyf|l zw?pIwT0`PrxA*4=v1L@M{=WWCp;0-g0SJ0$eSMYoR;p6irsvyggiOMv3eF9l2aqW{ zAQm-Y-->RD9W1cf5*Ab%PefCS4VydFy~#+--YP~N1f3ZWw0GcoBaea{irNE9yzPSA z05wSWr^Z5oz3BML9P}1ugREg}`pTEwFeKg)K?)D1+XyrT%11}GWlB#baB_Ty%k4ex zH>x)NQxb2`Aiw_Y>MdjW&aLIUEB9{82^fni7l+Kla)q^xQp@z#_re5%%#MVza)=*h zmor>}bv7KYA@dl#U>E~GHzZlW@RQg~;e5z|9fpi)94=y0!ln$(&*U|<?jL@!09uUj&-JvDr@_lb9AeXOQc6fE#rCz4luSSIt2dr4c5d7`T3mU)xU!$?kd?@e$Vzwi$`i=EaCjDC z&SA_sj5+uIG>Wqa9|Pf_@(eRCBBh9w;`=vSx%eb|La897f|SbpC~pOjm*5!v3)>ie A1poj5 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/helpers.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/helpers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04e82611a20b132aa8c051a3b97f955dcf6f6bd2 GIT binary patch literal 26533 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/logging.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/logging.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7dc94cad1819fd629eeeedb675103654ddc7df3a GIT binary patch literal 3447 zcmZ`*-ESMm5#QtI@mr!kQX59R3G_upCL6eE0Y-2?97#5!+5zmwD2sqR@s{LC$2)fS zD4Bws@JYv{|SSKL?^mplDbk*6de0ZU%@Be{(@h= z1BD>G{br~hE`)(5pa)I09w|f=!h*Z<9F)jIuoE(4^>`r;J7GPoM~(xZ!Oq`sTed<% zpV1S?fkM(pm~S^VTxW^T6rh8@*9uc?>dEwQHvX1;>EVi=oaCFFfv&UqG@Lf0`)-lU z+_%Vvq6)AS=Iqx^CL9?0f7)ocA(ZQ)R@(cpH28=Au?qM z$Jl3U)U>PAv1zGvAgV@I$`Ym08nrvt#=z(FH12QC$cU*-uu`o@*Ps@Vl>&&U;ORQ3X zaDpvrvVCUK^$#aKn5{BrV@R`&Bv%G8GvQUV<}#v276zXv?-B*Dz>AE6xD}MgXZ)@&`+YY&u#mq3JOX7?+U8U6ei2!(GK<}9@GFN4 zHBA&HTX8_2T{jW^#FgxbY8fT0Lie9<$Ttv8o#ZAwe_6hN@ZjE);M3Hiw=mwzh`PO* z3A)o~jCcK-)pFIrdBTk#d}&ok0yorv%(k42pChEZ;c}DXeB6egNE_VgGm3Kz^^2(L zKC0R#eU&6;p2ZiQ#urZFOWpWVd!v_}ZEu}Mr~4!veC?}Pa$M!l?{weVfQ6IfW*7R{ zW;eD8DHHi#Z|0Sce{hOUyv##nA7MS@Gk|-AT8!yTA5^2;z&D^p zw|lv~gEfUwfeQnS&ufmu^Cb|T_3A@WlCOK1FHg?m3g)W>fIBtF{{h#B<5W7^X;w>! zEzHt(Os20Zfy?WfqrI$&?`-_+7hAwxk;VuLpCicrvbKWa9&%as2)c%~ z(UT9}`5zowqnfT$P3k=?!Xspwtio7lJ-SNMD(6cB(@-*&?6U=?1TJ-IfTKH_Fv`eY z*FasYgPEus9x%EQNdE0X6+u6`LFp%%&#npE8WCOd-F6L zJ#Jw|Tz)kF_<|ht)a36|AEiDGKTe#eOI>xTqb_|NyYT4!lh{HxwtzHm0L?S?+*9@3 zr@0e#wX3dn)Ya42bo=Kr^Fcq1cn)9KPa4daEx;`IR&hTw>qd*kN)tXQ zS+U3wtoZ_Vap>HT(`vvixQgQ@4;bG&WX&pkj{r#X0PcsYro97*?R{}1ZvXPVjpEg7 z8&}`Geq+mx3e6IRogG4p{4(%7otTIL{szj5!<}r(%XAobBcq{oDNmwKnDbs8QP({j zyTX42YlurC2z}qLC`ymK-kE$(NwO_}JrZrpUyr0a!{?MNb|#-wa-lQ%ocaUDKZa{i zXfJTFGx_vG#24@T;>vuV47>0Auy%ajTYYs(0ob4HR>{oD$IIRHa%Uxfl773Je!HFO wk<>GC;VHS$3(U2*x`DaQ{Ed^q&2Hf4cYdGZ`xk+(FT3cR0^t9DI_akW0)B>u)Bpeg literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/sessions.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/sessions.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c6486ced39579177ee1f384019d487886a0d59d GIT binary patch literal 18635 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/signals.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/signals.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..013ec306f0b1b59094b20d8a955da5b354e36408 GIT binary patch literal 1358 zcmZ{jJx|*}9EZ(rBt*)DP3XcP$|pFi7&yzvEB29mn>v# zrA}EQvCxUC;v4i+oF%KWJRx=JQXwIAVCp%^p~S@}+q(Ptxxer6+22yBBw+1F;zQ+6 z1b|=ufVXI;BV7Fy0B8XPD1rv6LO~Gxeng8@qlKsdA^=6t7<$g$*W?q8hrzhC|zO6vs;ky6OVT_cNXDvO$t%WzUZ1QOgq811Mu#P2`U|ON zWYa7eIzfkoJ*0;p>$zdp+J*Zf!!+5mM5bWL6_hV)vd?ViM!h72X)A4TfA=mf1`rQC>eUIzIuD-|hA=me~KAY6mfxf=y>$7TY zeR!kq_2~EWJ+82$@AXA(eUIzIuKss$3%hTfQr)mKGOFkO)X01 z5!p5L#rcH=$x_*#vrk};y+TX!i|nzi{dVTfqwB=0s-e_0w1%fxRsWZ^{<6zuR1gFg z%+dbi0^Fzl$7LLhOn!R#dG*U`BXN9XF5Zlh<};&B?4$ zkanjZoQfwReY$Q>Z#dH%6im9=xl`#xqR-yi*)1o#MM1{BWevAP|E-}RHbk6e>i+=X C7-?Mq literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/templating.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/templating.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e589ef3bdbba2b5f8b0a6152b22b8e04e4d1cf00 GIT binary patch literal 10645 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/testing.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/testing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0506a6f2548e4db5570661ec15262b55affc1e0b GIT binary patch literal 14600 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/__pycache__/typing.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/__pycache__/typing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50a9acccf9d5ebb97b954558430f64d47e9b2355 GIT binary patch literal 3676 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 timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(App): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + default_config = ImmutableDict( + { + "DEBUG": None, + "TESTING": False, + "PROPAGATE_EXCEPTIONS": None, + "SECRET_KEY": None, + "SECRET_KEY_FALLBACKS": None, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "TRUSTED_HOSTS": None, + "SERVER_NAME": None, + "APPLICATION_ROOT": "/", + "SESSION_COOKIE_NAME": "session", + "SESSION_COOKIE_DOMAIN": None, + "SESSION_COOKIE_PATH": None, + "SESSION_COOKIE_HTTPONLY": True, + "SESSION_COOKIE_SECURE": False, + "SESSION_COOKIE_PARTITIONED": False, + "SESSION_COOKIE_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "MAX_FORM_MEMORY_SIZE": 500_000, + "MAX_FORM_PARTS": 1_000, + "SEND_FILE_MAX_AGE_DEFAULT": None, + "TRAP_BAD_REQUEST_ERRORS": None, + "TRAP_HTTP_EXCEPTIONS": False, + "EXPLAIN_TEMPLATE_LOADING": False, + "PREFERRED_URL_SCHEME": "http", + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + "PROVIDE_AUTOMATIC_OPTIONS": True, + } + ) + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class: type[Request] = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class: type[Response] = Response + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface: SessionInterface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_url_path=static_url_path, + static_folder=static_folder, + static_host=static_host, + host_matching=host_matching, + subdomain_matching=subdomain_matching, + template_folder=template_folder, + instance_path=instance_path, + instance_relative_config=instance_relative_config, + root_path=root_path, + ) + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = cli.AppGroup() + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert ( + bool(static_host) == host_matching + ), "Invalid static_host/host_matching combination" + # Use a weakref to avoid creating a reference cycle between the app + # and the view function (see #3761). + self_ref = weakref.ref(self) + self.add_url_rule( + f"{self.static_url_path}/", + endpoint="static", + host=static_host, + view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950 + ) + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value # type: ignore[no-any-return] + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource( + self, resource: str, mode: str = "rb", encoding: str | None = None + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is supported, + valid values are ``"r"`` (or ``"rt"``) and ``"rb"``. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + path = os.path.join(self.root_path, resource) + + if mode == "rb": + return open(path, mode) # pyright: ignore + + return open(path, mode, encoding=encoding) + + def open_instance_resource( + self, resource: str, mode: str = "rb", encoding: str | None = "utf-8" + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to the application's instance folder + :attr:`instance_path`. Unlike :meth:`open_resource`, files in the + instance folder can be opened for writing. + + :param resource: Path to the resource relative to :attr:`instance_path`. + :param mode: Open the file in this mode. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + path = os.path.join(self.instance_path, resource) + + if "b" in mode: + return open(path, mode) + + return open(path, mode, encoding=encoding) + + def create_jinja_environment(self) -> Environment: + """Create the Jinja environment based on :attr:`jinja_options` + and the various Jinja-related methods of the app. Changing + :attr:`jinja_options` after this will have no effect. Also adds + Flask-related globals and filters to the environment. + + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + + .. versionadded:: 0.5 + """ + options = dict(self.jinja_options) + + if "autoescape" not in options: + options["autoescape"] = self.select_jinja_autoescape + + if "auto_reload" not in options: + auto_reload = self.config["TEMPLATES_AUTO_RELOAD"] + + if auto_reload is None: + auto_reload = self.debug + + options["auto_reload"] = auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=self.url_for, + get_flashed_messages=get_flashed_messages, + config=self.config, + # request, session and g are normally added with the + # context processor for efficiency reasons but for imported + # templates we also want the proxies in there. + request=request, + session=session, + g=g, + ) + rv.policies["json.dumps_function"] = self.json.dumps + return rv + + def create_url_adapter(self, request: Request | None) -> MapAdapter | None: + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionchanged:: 3.1 + If :data:`SERVER_NAME` is set, it does not restrict requests to + only that domain, for both ``subdomain_matching`` and + ``host_matching``. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + + .. versionchanged:: 0.9 + This can be called outside a request when the URL adapter is created + for an application context. + + .. versionadded:: 0.6 + """ + if request is not None: + if (trusted_hosts := self.config["TRUSTED_HOSTS"]) is not None: + request.trusted_hosts = trusted_hosts + + # Check trusted_hosts here until bind_to_environ does. + request.host = get_host(request.environ, request.trusted_hosts) # pyright: ignore + subdomain = None + server_name = self.config["SERVER_NAME"] + + if self.url_map.host_matching: + # Don't pass SERVER_NAME, otherwise it's used and the actual + # host is ignored, which breaks host matching. + server_name = None + elif not self.subdomain_matching: + # Werkzeug doesn't implement subdomain matching yet. Until then, + # disable it by forcing the current subdomain to the default, or + # the empty string. + subdomain = self.url_map.default_subdomain or "" + + return self.url_map.bind_to_environ( + request.environ, server_name=server_name, subdomain=subdomain + ) + + # Need at least SERVER_NAME to match/build outside a request. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + def raise_routing_exception(self, request: Request) -> t.NoReturn: + """Intercept routing exceptions and possibly do something else. + + In debug mode, intercept a routing redirect and replace it with + an error if the body will be discarded. + + With modern Werkzeug this shouldn't occur, since it now uses a + 308 status which tells the browser to resend the method and + body. + + .. versionchanged:: 2.1 + Don't intercept 307 and 308 redirects. + + :meta private: + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.routing_exception.code in {307, 308} + or request.method in {"GET", "HEAD", "OPTIONS"} + ): + raise request.routing_exception # type: ignore[misc] + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def update_template_context(self, context: dict[str, t.Any]) -> None: + """Update the template context with some commonly used variables. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overridden if a context processor + decides to return a value with the same key. + + :param context: the context as a dictionary that is updated in place + to add extra variables. + """ + names: t.Iterable[str | None] = (None,) + + # A template may be rendered outside a request context. + if request: + names = chain(names, reversed(request.blueprints)) + + # The values passed to render_template take precedence. Keep a + # copy to re-apply after all context functions. + orig_ctx = context.copy() + + for name in names: + if name in self.template_context_processors: + for func in self.template_context_processors[name]: + context.update(self.ensure_sync(func)()) + + context.update(orig_ctx) + + def make_shell_context(self) -> dict[str, t.Any]: + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {"app": self, "g": g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + def run( + self, + host: str | None = None, + port: int | None = None, + debug: bool | None = None, + load_dotenv: bool = True, + **options: t.Any, + ) -> None: + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :doc:`/deploying/index` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Ignore this call so that it doesn't start another server if + # the 'flask run' command is used. + if os.environ.get("FLASK_RUN_FROM_CLI") == "true": + if not is_running_from_reloader(): + click.secho( + " * Ignoring a call to 'app.run()' that would block" + " the current 'flask' CLI command.\n" + " Only call 'app.run()' in an 'if __name__ ==" + ' "__main__"\' guard.', + fg="red", + ) + + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, env var overrides existing value + if "FLASK_DEBUG" in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + server_name = self.config.get("SERVER_NAME") + sn_host = sn_port = None + + if server_name: + sn_host, _, sn_port = server_name.partition(":") + + if not host: + if sn_host: + host = sn_host + else: + host = "127.0.0.1" + + if port or port == 0: + port = int(port) + elif sn_port: + port = int(sn_port) + else: + port = 5000 + + options.setdefault("use_reloader", self.debug) + options.setdefault("use_debugger", self.debug) + options.setdefault("threaded", True) + + cli.show_server_banner(self.debug, self.name) + + from werkzeug.serving import run_simple + + try: + run_simple(t.cast(str, host), port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient: + """Creates a test client for this application. For information + about unit testing head over to :doc:`/testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from .testing import FlaskClient as cls + return cls( # type: ignore + self, self.response_class, use_cookies=use_cookies, **kwargs + ) + + def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner: + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from .testing import FlaskCliRunner as cls + + return cls(self, **kwargs) # type: ignore + + def handle_http_exception( + self, e: HTTPException + ) -> HTTPException | ft.ResponseReturnValue: + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionchanged:: 1.0.3 + ``RoutingException``, used internally for actions such as + slash redirects during routing, is not passed to error + handlers. + + .. versionchanged:: 1.0 + Exceptions are looked up by code *and* by MRO, so + ``HTTPException`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + return e + + handler = self._find_error_handler(e, request.blueprints) + if handler is None: + return e + return self.ensure_sync(handler)(e) # type: ignore[no-any-return] + + def handle_user_exception( + self, e: Exception + ) -> HTTPException | ft.ResponseReturnValue: + """This method is called whenever an exception occurs that + should be handled. A special case is :class:`~werkzeug + .exceptions.HTTPException` which is forwarded to the + :meth:`handle_http_exception` method. This function will either + return a response value or reraise the exception with the same + traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the + bad key in debug mode rather than a generic bad request + message. + + .. versionadded:: 0.7 + """ + if isinstance(e, BadRequestKeyError) and ( + self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"] + ): + e.show_exception = True + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e, request.blueprints) + + if handler is None: + raise + + return self.ensure_sync(handler)(e) # type: ignore[no-any-return] + + def handle_exception(self, e: Exception) -> Response: + """Handle an exception that did not have an error handler + associated with it, or that was raised from an error handler. + This always causes a 500 ``InternalServerError``. + + Always sends the :data:`got_request_exception` signal. + + If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug + mode, the error will be re-raised so that the debugger can + display it. Otherwise, the original exception is logged, and + an :exc:`~werkzeug.exceptions.InternalServerError` is returned. + + If an error handler is registered for ``InternalServerError`` or + ``500``, it will be used. For consistency, the handler will + always receive the ``InternalServerError``. The original + unhandled exception is available as ``e.original_exception``. + + .. versionchanged:: 1.1.0 + Always passes the ``InternalServerError`` instance to the + handler, setting ``original_exception`` to the unhandled + error. + + .. versionchanged:: 1.1.0 + ``after_request`` functions and other finalization is done + even for the default 500 response when there is no handler. + + .. versionadded:: 0.3 + """ + exc_info = sys.exc_info() + got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e) + propagate = self.config["PROPAGATE_EXCEPTIONS"] + + if propagate is None: + propagate = self.testing or self.debug + + if propagate: + # Re-raise if called with an active exception, otherwise + # raise the passed in exception. + if exc_info[1] is e: + raise + + raise e + + self.log_exception(exc_info) + server_error: InternalServerError | ft.ResponseReturnValue + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error, request.blueprints) + + if handler is not None: + server_error = self.ensure_sync(handler)(server_error) + + return self.finalize_request(server_error, from_error_handler=True) + + def log_exception( + self, + exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]), + ) -> None: + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error( + f"Exception on {request.path} [{request.method}]", exc_info=exc_info + ) + + def dispatch_request(self) -> ft.ResponseReturnValue: + """Does the request dispatching. Matches the URL and returns the + return value of the view or error handler. This does not have to + be a response object. In order to convert the return value to a + proper response object, call :func:`make_response`. + + .. versionchanged:: 0.7 + This no longer does the exception handling, this code was + moved to the new :meth:`full_dispatch_request`. + """ + req = request_ctx.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule: Rule = req.url_rule # type: ignore[assignment] + # if we provide automatic options for this URL and the + # request came with the OPTIONS method, reply automatically + if ( + getattr(rule, "provide_automatic_options", False) + and req.method == "OPTIONS" + ): + return self.make_default_options_response() + # otherwise dispatch to the handler for that endpoint + view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment] + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] + + def full_dispatch_request(self) -> Response: + """Dispatches the request and on top of that performs request + pre and postprocessing as well as HTTP exception catching and + error handling. + + .. versionadded:: 0.7 + """ + self._got_first_request = True + + try: + request_started.send(self, _async_wrapper=self.ensure_sync) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request( + self, + rv: ft.ResponseReturnValue | HTTPException, + from_error_handler: bool = False, + ) -> Response: + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send( + self, _async_wrapper=self.ensure_sync, response=response + ) + except Exception: + if not from_error_handler: + raise + self.logger.exception( + "Request finalizing failed with an error while handling an error" + ) + return response + + def make_default_options_response(self) -> Response: + """This method is called to create the default ``OPTIONS`` response. + This can be changed through subclassing to change the default + behavior of ``OPTIONS`` responses. + + .. versionadded:: 0.7 + """ + adapter = request_ctx.url_adapter + methods = adapter.allowed_methods() # type: ignore[union-attr] + rv = self.response_class() + rv.allow.update(methods) + return rv + + def ensure_sync(self, func: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Ensure that the function is synchronous for WSGI workers. + Plain ``def`` functions are returned as-is. ``async def`` + functions are wrapped to run and wait for the response. + + Override this method to change how the app runs async views. + + .. versionadded:: 2.0 + """ + if iscoroutinefunction(func): + return self.async_to_sync(func) + + return func + + def async_to_sync( + self, func: t.Callable[..., t.Coroutine[t.Any, t.Any, t.Any]] + ) -> t.Callable[..., t.Any]: + """Return a sync function that will run the coroutine function. + + .. code-block:: python + + result = app.async_to_sync(func)(*args, **kwargs) + + Override this method to change how the app converts async code + to be synchronously callable. + + .. versionadded:: 2.0 + """ + try: + from asgiref.sync import async_to_sync as asgiref_async_to_sync + except ImportError: + raise RuntimeError( + "Install Flask with the 'async' extra in order to use async views." + ) from None + + return asgiref_async_to_sync(func) + + def url_for( + self, + /, + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, + ) -> str: + """Generate a URL to the given endpoint with the given values. + + This is called by :func:`flask.url_for`, and can be called + directly as well. + + An *endpoint* is the name of a URL rule, usually added with + :meth:`@app.route() `, and usually the same name as the + view function. A route defined in a :class:`~flask.Blueprint` + will prepend the blueprint's name separated by a ``.`` to the + endpoint. + + In some cases, such as email messages, you want URLs to include + the scheme and domain, like ``https://example.com/hello``. When + not in an active request, URLs will be external by default, but + this requires setting :data:`SERVER_NAME` so Flask knows what + domain to use. :data:`APPLICATION_ROOT` and + :data:`PREFERRED_URL_SCHEME` should also be configured as + needed. This config is only used when not in an active request. + + Functions can be decorated with :meth:`url_defaults` to modify + keyword arguments before the URL is built. + + If building fails for some reason, such as an unknown endpoint + or incorrect values, the app's :meth:`handle_url_build_error` + method is called. If that returns a string, that is returned, + otherwise a :exc:`~werkzeug.routing.BuildError` is raised. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it + is external. + :param _external: If given, prefer the URL to be internal + (False) or require it to be external (True). External URLs + include the scheme and domain. When not in an active + request, URLs are external by default. + :param values: Values to use for the variable parts of the URL + rule. Unknown keys are appended as query string arguments, + like ``?a=b&c=d``. + + .. versionadded:: 2.2 + Moved from ``flask.url_for``, which calls this method. + """ + req_ctx = _cv_request.get(None) + + if req_ctx is not None: + url_adapter = req_ctx.url_adapter + blueprint_name = req_ctx.request.blueprint + + # If the endpoint starts with "." and the request matches a + # blueprint, the endpoint is relative to the blueprint. + if endpoint[:1] == ".": + if blueprint_name is not None: + endpoint = f"{blueprint_name}{endpoint}" + else: + endpoint = endpoint[1:] + + # When in a request, generate a URL without scheme and + # domain by default, unless a scheme is given. + if _external is None: + _external = _scheme is not None + else: + app_ctx = _cv_app.get(None) + + # If called by helpers.url_for, an app context is active, + # use its url_adapter. Otherwise, app.url_for was called + # directly, build an adapter. + if app_ctx is not None: + url_adapter = app_ctx.url_adapter + else: + url_adapter = self.create_url_adapter(None) + + if url_adapter is None: + raise RuntimeError( + "Unable to build URLs outside an active request" + " without 'SERVER_NAME' configured. Also configure" + " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as" + " needed." + ) + + # When outside a request, generate a URL with scheme and + # domain by default. + if _external is None: + _external = True + + # It is an error to set _scheme when _external=False, in order + # to avoid accidental insecure URLs. + if _scheme is not None and not _external: + raise ValueError("When specifying '_scheme', '_external' must be True.") + + self.inject_url_defaults(endpoint, values) + + try: + rv = url_adapter.build( # type: ignore[union-attr] + endpoint, + values, + method=_method, + url_scheme=_scheme, + force_external=_external, + ) + except BuildError as error: + values.update( + _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external + ) + return self.handle_url_build_error(error, endpoint, values) + + if _anchor is not None: + _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@") + rv = f"{rv}#{_anchor}" + + return rv + + def make_response(self, rv: ft.ResponseReturnValue) -> Response: + """Convert the return value from a view function to an instance of + :attr:`response_class`. + + :param rv: the return value from the view function. The view function + must return a response. Returning ``None``, or the view ending + without returning, is not allowed. The following types are allowed + for ``view_rv``: + + ``str`` + A response object is created with the string encoded to UTF-8 + as the body. + + ``bytes`` + A response object is created with the bytes as the body. + + ``dict`` + A dictionary that will be jsonify'd before being returned. + + ``list`` + A list that will be jsonify'd before being returned. + + ``generator`` or ``iterator`` + A generator that returns ``str`` or ``bytes`` to be + streamed as the response. + + ``tuple`` + Either ``(body, status, headers)``, ``(body, status)``, or + ``(body, headers)``, where ``body`` is any of the other types + allowed here, ``status`` is a string or an integer, and + ``headers`` is a dictionary or a list of ``(key, value)`` + tuples. If ``body`` is a :attr:`response_class` instance, + ``status`` overwrites the exiting value and ``headers`` are + extended. + + :attr:`response_class` + The object is returned unchanged. + + other :class:`~werkzeug.wrappers.Response` class + The object is coerced to :attr:`response_class`. + + :func:`callable` + The function is called as a WSGI application. The result is + used to create a response object. + + .. versionchanged:: 2.2 + A generator will be converted to a streaming response. + A list will be converted to a JSON response. + + .. versionchanged:: 1.1 + A dict will be converted to a JSON response. + + .. versionchanged:: 0.9 + Previously a tuple was interpreted as the arguments for the + response object. + """ + + status: int | None = None + headers: HeadersValue | None = None + + # unpack tuple returns + if isinstance(rv, tuple): + len_rv = len(rv) + + # a 3-tuple is unpacked directly + if len_rv == 3: + rv, status, headers = rv # type: ignore[misc] + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv # pyright: ignore + else: + rv, status = rv # type: ignore[assignment,misc] + # other sized tuples are not allowed + else: + raise TypeError( + "The view function did not return a valid response tuple." + " The tuple must have the form (body, status, headers)," + " (body, status), or (body, headers)." + ) + + # the body must not be None + if rv is None: + raise TypeError( + f"The view function for {request.endpoint!r} did not" + " return a valid response. The function either returned" + " None or ended without a return statement." + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, cabc.Iterator): + # let the response class set the status and headers instead of + # waiting to do it manually, so that the class can handle any + # special logic + rv = self.response_class( + rv, + status=status, + headers=headers, # type: ignore[arg-type] + ) + status = headers = None + elif isinstance(rv, (dict, list)): + rv = self.json.response(rv) + elif isinstance(rv, BaseResponse) or callable(rv): + # evaluate a WSGI callable, or coerce a different response + # class to the correct type + try: + rv = self.response_class.force_type( + rv, # type: ignore[arg-type] + request.environ, + ) + except TypeError as e: + raise TypeError( + f"{e}\nThe view function did not return a valid" + " response. The return type must be a string," + " dict, list, tuple with headers or status," + " Response instance, or WSGI callable, but it" + f" was a {type(rv).__name__}." + ).with_traceback(sys.exc_info()[2]) from None + else: + raise TypeError( + "The view function did not return a valid" + " response. The return type must be a string," + " dict, list, tuple with headers or status," + " Response instance, or WSGI callable, but it was a" + f" {type(rv).__name__}." + ) + + rv = t.cast(Response, rv) + # prefer the status if it was provided + if status is not None: + if isinstance(status, (str, bytes, bytearray)): + rv.status = status + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.update(headers) + + return rv + + def preprocess_request(self) -> ft.ResponseReturnValue | None: + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + names = (None, *reversed(request.blueprints)) + + for name in names: + if name in self.url_value_preprocessors: + for url_func in self.url_value_preprocessors[name]: + url_func(request.endpoint, request.view_args) + + for name in names: + if name in self.before_request_funcs: + for before_func in self.before_request_funcs[name]: + rv = self.ensure_sync(before_func)() + + if rv is not None: + return rv # type: ignore[no-any-return] + + return None + + def process_response(self, response: Response) -> Response: + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = request_ctx._get_current_object() # type: ignore[attr-defined] + + for func in ctx._after_request_functions: + response = self.ensure_sync(func)(response) + + for name in chain(request.blueprints, (None,)): + if name in self.after_request_funcs: + for func in reversed(self.after_request_funcs[name]): + response = self.ensure_sync(func)(response) + + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + + return response + + def do_teardown_request( + self, + exc: BaseException | None = _sentinel, # type: ignore[assignment] + ) -> None: + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for name in chain(request.blueprints, (None,)): + if name in self.teardown_request_funcs: + for func in reversed(self.teardown_request_funcs[name]): + self.ensure_sync(func)(exc) + + request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def do_teardown_appcontext( + self, + exc: BaseException | None = _sentinel, # type: ignore[assignment] + ) -> None: + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for func in reversed(self.teardown_appcontext_funcs): + self.ensure_sync(func)(exc) + + appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def app_context(self) -> AppContext: + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ: WSGIEnvironment) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with app.test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from .testing import EnvironBuilder + + builder = EnvironBuilder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app( + self, environ: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error: BaseException | None = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: # noqa: B001 + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if "werkzeug.debug.preserve_context" in environ: + environ["werkzeug.debug.preserve_context"](_cv_app.get()) + environ["werkzeug.debug.preserve_context"](_cv_request.get()) + + if error is not None and self.should_ignore_error(error): + error = None + + ctx.pop(error) + + def __call__( + self, environ: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """The WSGI server calls the Flask application object as the + WSGI application. This calls :meth:`wsgi_app`, which can be + wrapped to apply middleware. + """ + return self.wsgi_app(environ, start_response) diff --git a/.venv/lib/python3.11/site-packages/flask/blueprints.py b/.venv/lib/python3.11/site-packages/flask/blueprints.py new file mode 100644 index 0000000..b6d4e43 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/blueprints.py @@ -0,0 +1,128 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +from .cli import AppGroup +from .globals import current_app +from .helpers import send_from_directory +from .sansio.blueprints import Blueprint as SansioBlueprint +from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa +from .sansio.scaffold import _sentinel + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore + ) -> None: + super().__init__( + name, + import_name, + static_folder, + static_url_path, + template_folder, + url_prefix, + subdomain, + url_defaults, + root_path, + cli_group, + ) + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = AppGroup() + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value # type: ignore[no-any-return] + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource( + self, resource: str, mode: str = "rb", encoding: str | None = "utf-8" + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for reading. The + blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource` + method. + + :param resource: Path to the resource relative to :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is supported, + valid values are ``"r"`` (or ``"rt"``) and ``"rb"``. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + path = os.path.join(self.root_path, resource) + + if mode == "rb": + return open(path, mode) # pyright: ignore + + return open(path, mode, encoding=encoding) diff --git a/.venv/lib/python3.11/site-packages/flask/cli.py b/.venv/lib/python3.11/site-packages/flask/cli.py new file mode 100644 index 0000000..dd03f3c --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/cli.py @@ -0,0 +1,1133 @@ +from __future__ import annotations + +import ast +import collections.abc as cabc +import importlib.metadata +import inspect +import os +import platform +import re +import sys +import traceback +import typing as t +from functools import update_wrapper +from operator import itemgetter +from types import ModuleType + +import click +from click.core import ParameterSource +from werkzeug import run_simple +from werkzeug.serving import is_running_from_reloader +from werkzeug.utils import import_string + +from .globals import current_app +from .helpers import get_debug_flag +from .helpers import get_load_dotenv + +if t.TYPE_CHECKING: + import ssl + + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module: ModuleType) -> Flask: + """Given a module instance this tries to find the best possible + application in the module or raises an exception. + """ + from . import Flask + + # Search for the most common names first. + for attr_name in ("app", "application"): + app = getattr(module, attr_name, None) + + if isinstance(app, Flask): + return app + + # Otherwise find the only object that is a Flask instance. + matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] + + if len(matches) == 1: + return matches[0] + elif len(matches) > 1: + raise NoAppException( + "Detected multiple Flask applications in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify the correct one." + ) + + # Search for app factory functions. + for attr_name in ("create_app", "make_app"): + app_factory = getattr(module, attr_name, None) + + if inspect.isfunction(app_factory): + try: + app = app_factory() + + if isinstance(app, Flask): + return app + except TypeError as e: + if not _called_with_wrong_args(app_factory): + raise + + raise NoAppException( + f"Detected factory '{attr_name}' in module '{module.__name__}'," + " but could not call it without arguments. Use" + f" '{module.__name__}:{attr_name}(args)'" + " to specify arguments." + ) from e + + raise NoAppException( + "Failed to find Flask application or factory in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify one." + ) + + +def _called_with_wrong_args(f: t.Callable[..., Flask]) -> bool: + """Check whether calling a function raised a ``TypeError`` because + the call failed or because something in the factory raised the + error. + + :param f: The function that was called. + :return: ``True`` if the call failed. + """ + tb = sys.exc_info()[2] + + try: + while tb is not None: + if tb.tb_frame.f_code is f.__code__: + # In the function, it was called successfully. + return False + + tb = tb.tb_next + + # Didn't reach the function. + return True + finally: + # Delete tb to break a circular reference. + # https://docs.python.org/2/library/sys.html#sys.exc_info + del tb + + +def find_app_by_string(module: ModuleType, app_name: str) -> Flask: + """Check if the given string is a variable name or a function. Call + a function to get the app instance, or return the variable directly. + """ + from . import Flask + + # Parse app_name as a single expression to determine if it's a valid + # attribute name or function call. + try: + expr = ast.parse(app_name.strip(), mode="eval").body + except SyntaxError: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) from None + + if isinstance(expr, ast.Name): + name = expr.id + args = [] + kwargs = {} + elif isinstance(expr, ast.Call): + # Ensure the function name is an attribute name only. + if not isinstance(expr.func, ast.Name): + raise NoAppException( + f"Function reference must be a simple name: {app_name!r}." + ) + + name = expr.func.id + + # Parse the positional and keyword arguments as literals. + try: + args = [ast.literal_eval(arg) for arg in expr.args] + kwargs = { + kw.arg: ast.literal_eval(kw.value) + for kw in expr.keywords + if kw.arg is not None + } + except ValueError: + # literal_eval gives cryptic error messages, show a generic + # message with the full expression instead. + raise NoAppException( + f"Failed to parse arguments as literal values: {app_name!r}." + ) from None + else: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) + + try: + attr = getattr(module, name) + except AttributeError as e: + raise NoAppException( + f"Failed to find attribute {name!r} in {module.__name__!r}." + ) from e + + # If the attribute is a function, call it with any args and kwargs + # to get the real application. + if inspect.isfunction(attr): + try: + app = attr(*args, **kwargs) + except TypeError as e: + if not _called_with_wrong_args(attr): + raise + + raise NoAppException( + f"The factory {app_name!r} in module" + f" {module.__name__!r} could not be called with the" + " specified arguments." + ) from e + else: + app = attr + + if isinstance(app, Flask): + return app + + raise NoAppException( + "A valid Flask application was not obtained from" + f" '{module.__name__}:{app_name}'." + ) + + +def prepare_import(path: str) -> str: + """Given a filename this will try to calculate the python path, add it + to the search path and return the actual module name that is expected. + """ + path = os.path.realpath(path) + + fname, ext = os.path.splitext(path) + if ext == ".py": + path = fname + + if os.path.basename(path) == "__init__": + path = os.path.dirname(path) + + module_name = [] + + # move up until outside package structure (no __init__.py) + while True: + path, name = os.path.split(path) + module_name.append(name) + + if not os.path.exists(os.path.join(path, "__init__.py")): + break + + if sys.path[0] != path: + sys.path.insert(0, path) + + return ".".join(module_name[::-1]) + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[True] = True +) -> Flask: ... + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[False] = ... +) -> Flask | None: ... + + +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: bool = True +) -> Flask | None: + try: + __import__(module_name) + except ImportError: + # Reraise the ImportError if it occurred within the imported module. + # Determine this by checking whether the trace has a depth > 1. + if sys.exc_info()[2].tb_next: # type: ignore[union-attr] + raise NoAppException( + f"While importing {module_name!r}, an ImportError was" + f" raised:\n\n{traceback.format_exc()}" + ) from None + elif raise_if_not_found: + raise NoAppException(f"Could not import {module_name!r}.") from None + else: + return None + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(module) + else: + return find_app_by_string(module, app_name) + + +def get_version(ctx: click.Context, param: click.Parameter, value: t.Any) -> None: + if not value or ctx.resilient_parsing: + return + + flask_version = importlib.metadata.version("flask") + werkzeug_version = importlib.metadata.version("werkzeug") + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {flask_version}\n" + f"Werkzeug {werkzeug_version}", + color=ctx.color, + ) + ctx.exit() + + +version_option = click.Option( + ["--version"], + help="Show the Flask version.", + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True, +) + + +class ScriptInfo: + """Helper object to deal with Flask applications. This is usually not + necessary to interface with as it's used internally in the dispatching + to click. In future versions of Flask this object will most likely play + a bigger role. Typically it's created automatically by the + :class:`FlaskGroup` but you can also manually create it and pass it + onwards as click object. + + .. versionchanged:: 3.1 + Added the ``load_dotenv_defaults`` parameter and attribute. + """ + + def __init__( + self, + app_import_path: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: bool = True, + load_dotenv_defaults: bool = True, + ) -> None: + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path + #: Optionally a function that is passed the script info to create + #: the instance of the application. + self.create_app = create_app + #: A dictionary with arbitrary data that can be associated with + #: this script info. + self.data: dict[t.Any, t.Any] = {} + self.set_debug_flag = set_debug_flag + + self.load_dotenv_defaults = get_load_dotenv(load_dotenv_defaults) + """Whether default ``.flaskenv`` and ``.env`` files should be loaded. + + ``ScriptInfo`` doesn't load anything, this is for reference when doing + the load elsewhere during processing. + + .. versionadded:: 3.1 + """ + + self._loaded_app: Flask | None = None + + def load_app(self) -> Flask: + """Loads the Flask app (if not yet loaded) and returns it. Calling + this multiple times will just result in the already loaded app to + be returned. + """ + if self._loaded_app is not None: + return self._loaded_app + app: Flask | None = None + if self.create_app is not None: + app = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, maxsplit=1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(import_name, None, raise_if_not_found=False) + + if app is not None: + break + + if app is None: + raise NoAppException( + "Could not locate a Flask application. Use the" + " 'flask --app' option, 'FLASK_APP' environment" + " variable, or a 'wsgi.py' or 'app.py' file in the" + " current directory." + ) + + if self.set_debug_flag: + # Update the app's debug flag through the descriptor so that + # other values repopulate as well. + app.debug = get_debug_flag() + + self._loaded_app = app + return app + + +pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def with_appcontext(f: F) -> F: + """Wraps a callback so that it's guaranteed to be executed with the + script's application context. + + Custom commands (and their options) registered under ``app.cli`` or + ``blueprint.cli`` will always have an app context available, this + decorator is not required in that case. + + .. versionchanged:: 2.2 + The app context is active for subcommands as well as the + decorated callback. The app context is always available to + ``app.cli`` command and parameter callbacks. + """ + + @click.pass_context + def decorator(ctx: click.Context, /, *args: t.Any, **kwargs: t.Any) -> t.Any: + if not current_app: + app = ctx.ensure_object(ScriptInfo).load_app() + ctx.with_resource(app.app_context()) + + return ctx.invoke(f, *args, **kwargs) + + return update_wrapper(decorator, f) # type: ignore[return-value] + + +class AppGroup(click.Group): + """This works similar to a regular click :class:`~click.Group` but it + changes the behavior of the :meth:`command` decorator so that it + automatically wraps the functions in :func:`with_appcontext`. + + Not to be confused with :class:`FlaskGroup`. + """ + + def command( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Command]: + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` + unless it's disabled by passing ``with_appcontext=False``. + """ + wrap_for_ctx = kwargs.pop("with_appcontext", True) + + def decorator(f: t.Callable[..., t.Any]) -> click.Command: + if wrap_for_ctx: + f = with_appcontext(f) + return super(AppGroup, self).command(*args, **kwargs)(f) # type: ignore[no-any-return] + + return decorator + + def group( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Group]: + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it defaults the group class to + :class:`AppGroup`. + """ + kwargs.setdefault("cls", AppGroup) + return super().group(*args, **kwargs) # type: ignore[no-any-return] + + +def _set_app(ctx: click.Context, param: click.Option, value: str | None) -> str | None: + if value is None: + return None + + info = ctx.ensure_object(ScriptInfo) + info.app_import_path = value + return value + + +# This option is eager so the app will be available if --help is given. +# --help is also eager, so --app must be before it in the param list. +# no_args_is_help bypasses eager processing, so this option must be +# processed manually in that case to ensure FLASK_APP gets picked up. +_app_option = click.Option( + ["-A", "--app"], + metavar="IMPORT", + help=( + "The Flask application or factory function to load, in the form 'module:name'." + " Module can be a dotted import or file path. Name is not required if it is" + " 'app', 'application', 'create_app', or 'make_app', and can be 'name(args)' to" + " pass arguments." + ), + is_eager=True, + expose_value=False, + callback=_set_app, +) + + +def _set_debug(ctx: click.Context, param: click.Option, value: bool) -> bool | None: + # If the flag isn't provided, it will default to False. Don't use + # that, let debug be set by env in that case. + source = ctx.get_parameter_source(param.name) # type: ignore[arg-type] + + if source is not None and source in ( + ParameterSource.DEFAULT, + ParameterSource.DEFAULT_MAP, + ): + return None + + # Set with env var instead of ScriptInfo.load so that it can be + # accessed early during a factory function. + os.environ["FLASK_DEBUG"] = "1" if value else "0" + return value + + +_debug_option = click.Option( + ["--debug/--no-debug"], + help="Set debug mode.", + expose_value=False, + callback=_set_debug, +) + + +def _env_file_callback( + ctx: click.Context, param: click.Option, value: str | None +) -> str | None: + try: + import dotenv # noqa: F401 + except ImportError: + # Only show an error if a value was passed, otherwise we still want to + # call load_dotenv and show a message without exiting. + if value is not None: + raise click.BadParameter( + "python-dotenv must be installed to load an env file.", + ctx=ctx, + param=param, + ) from None + + # Load if a value was passed, or we want to load default files, or both. + if value is not None or ctx.obj.load_dotenv_defaults: + load_dotenv(value, load_defaults=ctx.obj.load_dotenv_defaults) + + return value + + +# This option is eager so env vars are loaded as early as possible to be +# used by other options. +_env_file_option = click.Option( + ["-e", "--env-file"], + type=click.Path(exists=True, dir_okay=False), + help=( + "Load environment variables from this file, taking precedence over" + " those set by '.env' and '.flaskenv'. Variables set directly in the" + " environment take highest precedence. python-dotenv must be installed." + ), + is_eager=True, + expose_value=False, + callback=_env_file_callback, +) + + +class FlaskGroup(AppGroup): + """Special subclass of the :class:`AppGroup` group that supports + loading more commands from the configured Flask app. Normally a + developer does not have to interface with this class but there are + some very advanced use cases for which it makes sense to create an + instance of this. see :ref:`custom-scripts`. + + :param add_default_commands: if this is True then the default run and + shell commands will be added. + :param add_version_option: adds the ``--version`` option. + :param create_app: an optional callback that is passed the script info and + returns the loaded app. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param set_debug_flag: Set the app's debug flag. + + .. versionchanged:: 3.1 + ``-e path`` takes precedence over default ``.env`` and ``.flaskenv`` files. + + .. versionchanged:: 2.2 + Added the ``-A/--app``, ``--debug/--no-debug``, ``-e/--env-file`` options. + + .. versionchanged:: 2.2 + An app context is pushed when running ``app.cli`` commands, so + ``@with_appcontext`` is no longer required for those commands. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment variables + from :file:`.env` and :file:`.flaskenv` files. + """ + + def __init__( + self, + add_default_commands: bool = True, + create_app: t.Callable[..., Flask] | None = None, + add_version_option: bool = True, + load_dotenv: bool = True, + set_debug_flag: bool = True, + **extra: t.Any, + ) -> None: + params: list[click.Parameter] = list(extra.pop("params", None) or ()) + # Processing is done with option callbacks instead of a group + # callback. This allows users to make a custom group callback + # without losing the behavior. --env-file must come first so + # that it is eagerly evaluated before --app. + params.extend((_env_file_option, _app_option, _debug_option)) + + if add_version_option: + params.append(version_option) + + if "context_settings" not in extra: + extra["context_settings"] = {} + + extra["context_settings"].setdefault("auto_envvar_prefix", "FLASK") + + super().__init__(params=params, **extra) + + self.create_app = create_app + self.load_dotenv = load_dotenv + self.set_debug_flag = set_debug_flag + + if add_default_commands: + self.add_command(run_command) + self.add_command(shell_command) + self.add_command(routes_command) + + self._loaded_plugin_commands = False + + def _load_plugin_commands(self) -> None: + if self._loaded_plugin_commands: + return + + if sys.version_info >= (3, 10): + from importlib import metadata + else: + # Use a backport on Python < 3.10. We technically have + # importlib.metadata on 3.8+, but the API changed in 3.10, + # so use the backport for consistency. + import importlib_metadata as metadata # pyright: ignore + + for ep in metadata.entry_points(group="flask.commands"): + self.add_command(ep.load(), ep.name) + + self._loaded_plugin_commands = True + + def get_command(self, ctx: click.Context, name: str) -> click.Command | None: + self._load_plugin_commands() + # Look up built-in and plugin commands, which should be + # available even if the app fails to load. + rv = super().get_command(ctx, name) + + if rv is not None: + return rv + + info = ctx.ensure_object(ScriptInfo) + + # Look up commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + app = info.load_app() + except NoAppException as e: + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + return None + + # Push an app context for the loaded app unless it is already + # active somehow. This makes the context available to parameter + # and command callbacks without needing @with_appcontext. + if not current_app or current_app._get_current_object() is not app: # type: ignore[attr-defined] + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + def list_commands(self, ctx: click.Context) -> list[str]: + self._load_plugin_commands() + # Start with the built-in and plugin commands. + rv = set(super().list_commands(ctx)) + info = ctx.ensure_object(ScriptInfo) + + # Add commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + rv.update(info.load_app().cli.list_commands(ctx)) + except NoAppException as e: + # When an app couldn't be loaded, show the error message + # without the traceback. + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + except Exception: + # When any other errors occurred during loading, show the + # full traceback. + click.secho(f"{traceback.format_exc()}\n", err=True, fg="red") + + return sorted(rv) + + def make_context( + self, + info_name: str | None, + args: list[str], + parent: click.Context | None = None, + **extra: t.Any, + ) -> click.Context: + # Set a flag to tell app.run to become a no-op. If app.run was + # not in a __name__ == __main__ guard, it would start the server + # when importing, blocking whatever command is being called. + os.environ["FLASK_RUN_FROM_CLI"] = "true" + + if "obj" not in extra and "obj" not in self.context_settings: + extra["obj"] = ScriptInfo( + create_app=self.create_app, + set_debug_flag=self.set_debug_flag, + load_dotenv_defaults=self.load_dotenv, + ) + + return super().make_context(info_name, args, parent=parent, **extra) + + def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: + if not args and self.no_args_is_help: + # Attempt to load --env-file and --app early in case they + # were given as env vars. Otherwise no_args_is_help will not + # see commands from app.cli. + _env_file_option.handle_parse_result(ctx, {}, []) + _app_option.handle_parse_result(ctx, {}, []) + + return super().parse_args(ctx, args) + + +def _path_is_ancestor(path: str, other: str) -> bool: + """Take ``other`` and remove the length of ``path`` from it. Then join it + to ``path``. If it is the original value, ``path`` is an ancestor of + ``other``.""" + return os.path.join(path, other[len(path) :].lstrip(os.sep)) == other + + +def load_dotenv( + path: str | os.PathLike[str] | None = None, load_defaults: bool = True +) -> bool: + """Load "dotenv" files to set environment variables. A given path takes + precedence over ``.env``, which takes precedence over ``.flaskenv``. After + loading and combining these files, values are only set if the key is not + already set in ``os.environ``. + + This is a no-op if `python-dotenv`_ is not installed. + + .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme + + :param path: Load the file at this location. + :param load_defaults: Search for and load the default ``.flaskenv`` and + ``.env`` files. + :return: ``True`` if at least one env var was loaded. + + .. versionchanged:: 3.1 + Added the ``load_defaults`` parameter. A given path takes precedence + over default files. + + .. versionchanged:: 2.0 + The current directory is not changed to the location of the + loaded file. + + .. versionchanged:: 2.0 + When loading the env files, set the default encoding to UTF-8. + + .. versionchanged:: 1.1.0 + Returns ``False`` when python-dotenv is not installed, or when + the given path isn't a file. + + .. versionadded:: 1.0 + """ + try: + import dotenv + except ImportError: + if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"): + click.secho( + " * Tip: There are .env files present. Install python-dotenv" + " to use them.", + fg="yellow", + err=True, + ) + + return False + + data: dict[str, str | None] = {} + + if load_defaults: + for default_name in (".flaskenv", ".env"): + if not (default_path := dotenv.find_dotenv(default_name, usecwd=True)): + continue + + data |= dotenv.dotenv_values(default_path, encoding="utf-8") + + if path is not None and os.path.isfile(path): + data |= dotenv.dotenv_values(path, encoding="utf-8") + + for key, value in data.items(): + if key in os.environ or value is None: + continue + + os.environ[key] = value + + return bool(data) # True if at least one env var was loaded. + + +def show_server_banner(debug: bool, app_import_path: str | None) -> None: + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if is_running_from_reloader(): + return + + if app_import_path is not None: + click.echo(f" * Serving Flask app '{app_import_path}'") + + if debug is not None: + click.echo(f" * Debug mode: {'on' if debug else 'off'}") + + +class CertParamType(click.ParamType): + """Click option type for the ``--cert`` option. Allows either an + existing file, the string ``'adhoc'``, or an import for a + :class:`~ssl.SSLContext` object. + """ + + name = "path" + + def __init__(self) -> None: + self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) + + def convert( + self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + try: + import ssl + except ImportError: + raise click.BadParameter( + 'Using "--cert" requires Python to be compiled with SSL support.', + ctx, + param, + ) from None + + try: + return self.path_type(value, param, ctx) + except click.BadParameter: + value = click.STRING(value, param, ctx).lower() + + if value == "adhoc": + try: + import cryptography # noqa: F401 + except ImportError: + raise click.BadParameter( + "Using ad-hoc certificates requires the cryptography library.", + ctx, + param, + ) from None + + return value + + obj = import_string(value, silent=True) + + if isinstance(obj, ssl.SSLContext): + return obj + + raise + + +def _validate_key(ctx: click.Context, param: click.Parameter, value: t.Any) -> t.Any: + """The ``--key`` option must be specified when ``--cert`` is a file. + Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. + """ + cert = ctx.params.get("cert") + is_adhoc = cert == "adhoc" + + try: + import ssl + except ImportError: + is_context = False + else: + is_context = isinstance(cert, ssl.SSLContext) + + if value is not None: + if is_adhoc: + raise click.BadParameter( + 'When "--cert" is "adhoc", "--key" is not used.', ctx, param + ) + + if is_context: + raise click.BadParameter( + 'When "--cert" is an SSLContext object, "--key" is not used.', + ctx, + param, + ) + + if not cert: + raise click.BadParameter('"--cert" must also be specified.', ctx, param) + + ctx.params["cert"] = cert, value + + else: + if cert and not (is_adhoc or is_context): + raise click.BadParameter('Required when using "--cert".', ctx, param) + + return value + + +class SeparatedPathType(click.Path): + """Click option type that accepts a list of values separated by the + OS's path separator (``:``, ``;`` on Windows). Each value is + validated as a :class:`click.Path` type. + """ + + def convert( + self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + items = self.split_envvar_value(value) + # can't call no-arg super() inside list comprehension until Python 3.12 + super_convert = super().convert + return [super_convert(item, param, ctx) for item in items] + + +@click.command("run", short_help="Run a development server.") +@click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.") +@click.option("--port", "-p", default=5000, help="The port to bind to.") +@click.option( + "--cert", + type=CertParamType(), + help="Specify a certificate file to use HTTPS.", + is_eager=True, +) +@click.option( + "--key", + type=click.Path(exists=True, dir_okay=False, resolve_path=True), + callback=_validate_key, + expose_value=False, + help="The key file to use when specifying a certificate.", +) +@click.option( + "--reload/--no-reload", + default=None, + help="Enable or disable the reloader. By default the reloader " + "is active if debug is enabled.", +) +@click.option( + "--debugger/--no-debugger", + default=None, + help="Enable or disable the debugger. By default the debugger " + "is active if debug is enabled.", +) +@click.option( + "--with-threads/--without-threads", + default=True, + help="Enable or disable multithreading.", +) +@click.option( + "--extra-files", + default=None, + type=SeparatedPathType(), + help=( + "Extra files that trigger a reload on change. Multiple paths" + f" are separated by {os.path.pathsep!r}." + ), +) +@click.option( + "--exclude-patterns", + default=None, + type=SeparatedPathType(), + help=( + "Files matching these fnmatch patterns will not trigger a reload" + " on change. Multiple patterns are separated by" + f" {os.path.pathsep!r}." + ), +) +@pass_script_info +def run_command( + info: ScriptInfo, + host: str, + port: int, + reload: bool, + debugger: bool, + with_threads: bool, + cert: ssl.SSLContext | tuple[str, str | None] | t.Literal["adhoc"] | None, + extra_files: list[str] | None, + exclude_patterns: list[str] | None, +) -> None: + """Run a local development server. + + This server is for development purposes only. It does not provide + the stability, security, or performance of production WSGI servers. + + The reloader and debugger are enabled by default with the '--debug' + option. + """ + try: + app: WSGIApplication = info.load_app() # pyright: ignore + except Exception as e: + if is_running_from_reloader(): + # When reloading, print out the error immediately, but raise + # it later so the debugger or server can handle it. + traceback.print_exc() + err = e + + def app( + environ: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + raise err from None + + else: + # When not reloading, raise the error immediately so the + # command fails. + raise e from None + + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + show_server_banner(debug, info.app_import_path) + + run_simple( + host, + port, + app, + use_reloader=reload, + use_debugger=debugger, + threaded=with_threads, + ssl_context=cert, + extra_files=extra_files, + exclude_patterns=exclude_patterns, + ) + + +run_command.params.insert(0, _debug_option) + + +@click.command("shell", short_help="Run a shell in the app context.") +@with_appcontext +def shell_command() -> None: + """Run an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to its configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + + banner = ( + f"Python {sys.version} on {sys.platform}\n" + f"App: {current_app.import_name}\n" + f"Instance: {current_app.instance_path}" + ) + ctx: dict[str, t.Any] = {} + + # Support the regular Python interpreter startup script if someone + # is using it. + startup = os.environ.get("PYTHONSTARTUP") + if startup and os.path.isfile(startup): + with open(startup) as f: + eval(compile(f.read(), startup, "exec"), ctx) + + ctx.update(current_app.make_shell_context()) + + # Site, customize, or startup script can set a hook to call when + # entering interactive mode. The default one sets up readline with + # tab and history completion. + interactive_hook = getattr(sys, "__interactivehook__", None) + + if interactive_hook is not None: + try: + import readline + from rlcompleter import Completer + except ImportError: + pass + else: + # rlcompleter uses __main__.__dict__ by default, which is + # flask.__main__. Use the shell context instead. + readline.set_completer(Completer(ctx).complete) + + interactive_hook() + + code.interact(banner=banner, local=ctx) + + +@click.command("routes", short_help="Show the routes for the app.") +@click.option( + "--sort", + "-s", + type=click.Choice(("endpoint", "methods", "domain", "rule", "match")), + default="endpoint", + help=( + "Method to sort routes by. 'match' is the order that Flask will match routes" + " when dispatching a request." + ), +) +@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.") +@with_appcontext +def routes_command(sort: str, all_methods: bool) -> None: + """Show all registered routes with endpoints and methods.""" + rules = list(current_app.url_map.iter_rules()) + + if not rules: + click.echo("No routes were registered.") + return + + ignored_methods = set() if all_methods else {"HEAD", "OPTIONS"} + host_matching = current_app.url_map.host_matching + has_domain = any(rule.host if host_matching else rule.subdomain for rule in rules) + rows = [] + + for rule in rules: + row = [ + rule.endpoint, + ", ".join(sorted((rule.methods or set()) - ignored_methods)), + ] + + if has_domain: + row.append((rule.host if host_matching else rule.subdomain) or "") + + row.append(rule.rule) + rows.append(row) + + headers = ["Endpoint", "Methods"] + sorts = ["endpoint", "methods"] + + if has_domain: + headers.append("Host" if host_matching else "Subdomain") + sorts.append("domain") + + headers.append("Rule") + sorts.append("rule") + + try: + rows.sort(key=itemgetter(sorts.index(sort))) + except ValueError: + pass + + rows.insert(0, headers) + widths = [max(len(row[i]) for row in rows) for i in range(len(headers))] + rows.insert(1, ["-" * w for w in widths]) + template = " ".join(f"{{{i}:<{w}}}" for i, w in enumerate(widths)) + + for row in rows: + click.echo(template.format(*row)) + + +cli = FlaskGroup( + name="flask", + help="""\ +A general utility script for Flask applications. + +An application to load must be given with the '--app' option, +'FLASK_APP' environment variable, or with a 'wsgi.py' or 'app.py' file +in the current directory. +""", +) + + +def main() -> None: + cli.main() + + +if __name__ == "__main__": + main() diff --git a/.venv/lib/python3.11/site-packages/flask/config.py b/.venv/lib/python3.11/site-packages/flask/config.py new file mode 100644 index 0000000..34ef1a5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/config.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .sansio.app import App + + +T = t.TypeVar("T") + + +class ConfigAttribute(t.Generic[T]): + """Makes an attribute forward to the config""" + + def __init__( + self, name: str, get_converter: t.Callable[[t.Any], T] | None = None + ) -> None: + self.__name__ = name + self.get_converter = get_converter + + @t.overload + def __get__(self, obj: None, owner: None) -> te.Self: ... + + @t.overload + def __get__(self, obj: App, owner: type[App]) -> T: ... + + def __get__(self, obj: App | None, owner: type[App] | None = None) -> T | te.Self: + if obj is None: + return self + + rv = obj.config[self.__name__] + + if self.get_converter is not None: + rv = self.get_converter(rv) + + return rv # type: ignore[no-any-return] + + def __set__(self, obj: App, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): # type: ignore[type-arg] + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__( + self, + root_path: str | os.PathLike[str], + defaults: dict[str, t.Any] | None = None, + ) -> None: + super().__init__(defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name: str, silent: bool = False) -> bool: + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError( + f"The environment variable {variable_name!r} is not set" + " and as such configuration could not be loaded. Set" + " this variable and make it point to a configuration" + " file" + ) + return self.from_pyfile(rv, silent=silent) + + def from_prefixed_env( + self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + ) -> bool: + """Load any environment variables that start with ``FLASK_``, + dropping the prefix from the env key for the config key. Values + are passed through a loading function to attempt to convert them + to more specific types than strings. + + Keys are loaded in :func:`sorted` order. + + The default loading function attempts to parse values as any + valid JSON type, including dicts and lists. + + Specific items in nested dicts can be set by separating the + keys with double underscores (``__``). If an intermediate key + doesn't exist, it will be initialized to an empty dict. + + :param prefix: Load env vars that start with this prefix, + separated with an underscore (``_``). + :param loads: Pass each string value to this function and use + the returned value as the config value. If any error is + raised it is ignored and the value remains a string. The + default is :func:`json.loads`. + + .. versionadded:: 2.1 + """ + prefix = f"{prefix}_" + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + key = key.removeprefix(prefix) + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + if "__" not in key: + # A non-nested key, set directly. + self[key] = value + continue + + # Traverse nested dictionaries with keys separated by "__". + current = self + *parts, tail = key.split("__") + + for part in parts: + # If an intermediate dict does not exist, create it. + if part not in current: + current[part] = {} + + current = current[part] + + current[tail] = value + + return True + + def from_pyfile( + self, filename: str | os.PathLike[str], silent: bool = False + ) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: object | str) -> None: + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, str): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_file( + self, + filename: str | os.PathLike[str], + load: t.Callable[[t.IO[t.Any]], t.Mapping[str, t.Any]], + silent: bool = False, + text: bool = True, + ) -> bool: + """Update the values in the config from a file that is loaded + using the ``load`` parameter. The loaded data is passed to the + :meth:`from_mapping` method. + + .. code-block:: python + + import json + app.config.from_file("config.json", load=json.load) + + import tomllib + app.config.from_file("config.toml", load=tomllib.load, text=False) + + :param filename: The path to the data file. This can be an + absolute path or relative to the config root path. + :param load: A callable that takes a file handle and returns a + mapping of loaded data from the file. + :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` + implements a ``read`` method. + :param silent: Ignore the file if it doesn't exist. + :param text: Open the file in text or binary mode. + :return: ``True`` if the file was loaded successfully. + + .. versionchanged:: 2.3 + The ``text`` parameter was added. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename, "r" if text else "rb") as f: + obj = load(f) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + + return self.from_mapping(obj) + + def from_mapping( + self, mapping: t.Mapping[str, t.Any] | None = None, **kwargs: t.Any + ) -> bool: + """Updates the config like :meth:`update` ignoring items with + non-upper keys. + + :return: Always returns ``True``. + + .. versionadded:: 0.11 + """ + mappings: dict[str, t.Any] = {} + if mapping is not None: + mappings.update(mapping) + mappings.update(kwargs) + for key, value in mappings.items(): + if key.isupper(): + self[key] = value + return True + + def get_namespace( + self, namespace: str, lowercase: bool = True, trim_namespace: bool = True + ) -> dict[str, t.Any]: + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in self.items(): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace) :] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self) -> str: + return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/.venv/lib/python3.11/site-packages/flask/ctx.py b/.venv/lib/python3.11/site-packages/flask/ctx.py new file mode 100644 index 0000000..9b164d3 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/ctx.py @@ -0,0 +1,449 @@ +from __future__ import annotations + +import contextvars +import sys +import typing as t +from functools import update_wrapper +from types import TracebackType + +from werkzeug.exceptions import HTTPException + +from . import typing as ft +from .globals import _cv_app +from .globals import _cv_request +from .signals import appcontext_popped +from .signals import appcontext_pushed + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIEnvironment + + from .app import Flask + from .sessions import SessionMixin + from .wrappers import Request + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals: + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + # Define attr methods to let mypy know this is a namespace object + # that has arbitrary attributes. + + def __getattr__(self, name: str) -> t.Any: + try: + return self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def __setattr__(self, name: str, value: t.Any) -> None: + self.__dict__[name] = value + + def __delattr__(self, name: str) -> None: + try: + del self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def get(self, name: str, default: t.Any | None = None) -> t.Any: + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name: str, default: t.Any = _sentinel) -> t.Any: + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raising a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name: str, default: t.Any = None) -> t.Any: + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item: str) -> bool: + return item in self.__dict__ + + def __iter__(self) -> t.Iterator[str]: + return iter(self.__dict__) + + def __repr__(self) -> str: + ctx = _cv_app.get(None) + if ctx is not None: + return f"" + return object.__repr__(self) + + +def after_this_request( + f: ft.AfterRequestCallable[t.Any], +) -> ft.AfterRequestCallable[t.Any]: + """Executes a function after this request. This is useful to modify + response objects. The function is passed the response object and has + to return the same or a new one. + + Example:: + + @app.route('/') + def index(): + @after_this_request + def add_header(response): + response.headers['X-Foo'] = 'Parachute' + return response + return 'Hello World!' + + This is more useful if a function other than the view function wants to + modify a response. For instance think of a decorator that wants to add + some headers without converting the return value into a response object. + + .. versionadded:: 0.9 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'after_this_request' can only be used when a request" + " context is active, such as in a view function." + ) + + ctx._after_request_functions.append(f) + return f + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def copy_current_request_context(f: F) -> F: + """A helper function that decorates a function to retain the current + request context. This is useful when working with greenlets. The moment + the function is decorated a copy of the request context is created and + then pushed when the function is called. The current session is also + included in the copied request context. + + Example:: + + import gevent + from flask import copy_current_request_context + + @app.route('/') + def index(): + @copy_current_request_context + def do_some_work(): + # do some work here, it can access flask.request or + # flask.session like you would otherwise in the view function. + ... + gevent.spawn(do_some_work) + return 'Regular response' + + .. versionadded:: 0.10 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'copy_current_request_context' can only be used when a" + " request context is active, such as in a view function." + ) + + ctx = ctx.copy() + + def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any: + with ctx: # type: ignore[union-attr] + return ctx.app.ensure_sync(f)(*args, **kwargs) # type: ignore[union-attr] + + return update_wrapper(wrapper, f) # type: ignore[return-value] + + +def has_request_context() -> bool: + """If you have code that wants to test if a request context is there or + not this function can be used. For instance, you may want to take advantage + of request information if the request object is available, but fail + silently if it is unavailable. + + :: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and has_request_context(): + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + Alternatively you can also just test any of the context bound objects + (such as :class:`request` or :class:`g`) for truthness:: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and request: + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + .. versionadded:: 0.7 + """ + return _cv_request.get(None) is not None + + +def has_app_context() -> bool: + """Works like :func:`has_request_context` but for the application + context. You can also just do a boolean check on the + :data:`current_app` object instead. + + .. versionadded:: 0.9 + """ + return _cv_app.get(None) is not None + + +class AppContext: + """The app context contains application-specific information. An app + context is created and pushed at the beginning of each request if + one is not already active. An app context is also pushed when + running CLI commands. + """ + + def __init__(self, app: Flask) -> None: + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g: _AppCtxGlobals = app.app_ctx_globals_class() + self._cv_tokens: list[contextvars.Token[AppContext]] = [] + + def push(self) -> None: + """Binds the app context to the current context.""" + self._cv_tokens.append(_cv_app.set(self)) + appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync) + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the app context.""" + try: + if len(self._cv_tokens) == 1: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + ctx = _cv_app.get() + _cv_app.reset(self._cv_tokens.pop()) + + if ctx is not self: + raise AssertionError( + f"Popped wrong app context. ({ctx!r} instead of {self!r})" + ) + + appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync) + + def __enter__(self) -> AppContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + +class RequestContext: + """The request context contains per-request information. The Flask + app creates and pushes it at the beginning of the request, then pops + it at the end of the request. It will create the URL adapter and + request object for the WSGI environment provided. + + Do not attempt to use this class directly, instead use + :meth:`~flask.Flask.test_request_context` and + :meth:`~flask.Flask.request_context` to create this object. + + When the request context is popped, it will evaluate all the + functions registered on the application for teardown execution + (:meth:`~flask.Flask.teardown_request`). + + The request context is automatically popped at the end of the + request. When using the interactive debugger, the context will be + restored so ``request`` is still accessible. Similarly, the test + client can preserve the context after the request ends. However, + teardown functions may already have closed some resources such as + database connections. + """ + + def __init__( + self, + app: Flask, + environ: WSGIEnvironment, + request: Request | None = None, + session: SessionMixin | None = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + request.json_module = app.json + self.request: Request = request + self.url_adapter = None + try: + self.url_adapter = app.create_url_adapter(self.request) + except HTTPException as e: + self.request.routing_exception = e + self.flashes: list[tuple[str, str]] | None = None + self.session: SessionMixin | None = session + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions: list[ft.AfterRequestCallable[t.Any]] = [] + + self._cv_tokens: list[ + tuple[contextvars.Token[RequestContext], AppContext | None] + ] = [] + + def copy(self) -> RequestContext: + """Creates a copy of this request context with the same request object. + This can be used to move a request context to a different greenlet. + Because the actual request object is the same this cannot be used to + move a request context to a different thread unless access to the + request object is locked. + + .. versionadded:: 0.10 + + .. versionchanged:: 1.1 + The current session object is used instead of reloading the original + data. This prevents `flask.session` pointing to an out-of-date object. + """ + return self.__class__( + self.app, + environ=self.request.environ, + request=self.request, + session=self.session, + ) + + def match_request(self) -> None: + """Can be overridden by a subclass to hook into the matching + of the request. + """ + try: + result = self.url_adapter.match(return_rule=True) # type: ignore + self.request.url_rule, self.request.view_args = result # type: ignore + except HTTPException as e: + self.request.routing_exception = e + + def push(self) -> None: + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _cv_app.get(None) + + if app_ctx is None or app_ctx.app is not self.app: + app_ctx = self.app.app_context() + app_ctx.push() + else: + app_ctx = None + + self._cv_tokens.append((_cv_request.set(self), app_ctx)) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session(self.app, self.request) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + # Match the request URL after loading the session, so that the + # session is available in custom URL converters. + if self.url_adapter is not None: + self.match_request() + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + clear_request = len(self._cv_tokens) == 1 + + try: + if clear_request: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_request(exc) + + request_close = getattr(self.request, "close", None) + if request_close is not None: + request_close() + finally: + ctx = _cv_request.get() + token, app_ctx = self._cv_tokens.pop() + _cv_request.reset(token) + + # get rid of circular dependencies at the end of the request + # so that we don't require the GC to be active. + if clear_request: + ctx.request.environ["werkzeug.request"] = None + + if app_ctx is not None: + app_ctx.pop(exc) + + if ctx is not self: + raise AssertionError( + f"Popped wrong request context. ({ctx!r} instead of {self!r})" + ) + + def __enter__(self) -> RequestContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__} {self.request.url!r}" + f" [{self.request.method}] of {self.app.name}>" + ) diff --git a/.venv/lib/python3.11/site-packages/flask/debughelpers.py b/.venv/lib/python3.11/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..2c8c4c4 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/debughelpers.py @@ -0,0 +1,178 @@ +from __future__ import annotations + +import typing as t + +from jinja2.loaders import BaseLoader +from werkzeug.routing import RequestRedirect + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + +if t.TYPE_CHECKING: + from .sansio.scaffold import Scaffold + from .wrappers import Request + + +class UnexpectedUnicodeError(AssertionError, UnicodeError): + """Raised in places where we want some better error reporting for + unexpected unicode or binary data. + """ + + +class DebugFilesKeyError(KeyError, AssertionError): + """Raised from request.files during debugging. The idea is that it can + provide a better error message than just a generic KeyError/BadRequest. + """ + + def __init__(self, request: Request, key: str) -> None: + form_matches = request.form.getlist(key) + buf = [ + f"You tried to access the file {key!r} in the request.files" + " dictionary but it does not exist. The mimetype for the" + f" request is {request.mimetype!r} instead of" + " 'multipart/form-data' which means that no file contents" + " were transmitted. To fix this error you should provide" + ' enctype="multipart/form-data" in your form.' + ] + if form_matches: + names = ", ".join(repr(x) for x in form_matches) + buf.append( + "\n\nThe browser instead transmitted some file names. " + f"This was submitted: {names}" + ) + self.msg = "".join(buf) + + def __str__(self) -> str: + return self.msg + + +class FormDataRoutingRedirect(AssertionError): + """This exception is raised in debug mode if a routing redirect + would cause the browser to drop the method or body. This happens + when method is not GET, HEAD or OPTIONS and the status code is not + 307 or 308. + """ + + def __init__(self, request: Request) -> None: + exc = request.routing_exception + assert isinstance(exc, RequestRedirect) + buf = [ + f"A request was sent to '{request.url}', but routing issued" + f" a redirect to the canonical URL '{exc.new_url}'." + ] + + if f"{request.base_url}/" == exc.new_url.partition("?")[0]: + buf.append( + " The URL was defined with a trailing slash. Flask" + " will redirect to the URL with a trailing slash if it" + " was accessed without one." + ) + + buf.append( + " Send requests to the canonical URL, or use 307 or 308 for" + " routing redirects. Otherwise, browsers will drop form" + " data.\n\n" + "This exception is only raised in debug mode." + ) + super().__init__("".join(buf)) + + +def attach_enctype_error_multidict(request: Request) -> None: + """Patch ``request.files.__getitem__`` to raise a descriptive error + about ``enctype=multipart/form-data``. + + :param request: The request to patch. + :meta private: + """ + oldcls = request.files.__class__ + + class newcls(oldcls): # type: ignore[valid-type, misc] + def __getitem__(self, key: str) -> t.Any: + try: + return super().__getitem__(key) + except KeyError as e: + if key not in request.form: + raise + + raise DebugFilesKeyError(request, key).with_traceback( + e.__traceback__ + ) from None + + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader: BaseLoader) -> t.Iterator[str]: + yield f"class: {type(loader).__module__}.{type(loader).__name__}" + for key, value in sorted(loader.__dict__.items()): + if key.startswith("_"): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, str) for x in value): + continue + yield f"{key}:" + for item in value: + yield f" - {item}" + continue + elif not isinstance(value, (str, int, float, bool)): + continue + yield f"{key}: {value!r}" + + +def explain_template_loading_attempts( + app: App, + template: str, + attempts: list[ + tuple[ + BaseLoader, + Scaffold, + tuple[str, str | None, t.Callable[[], bool] | None] | None, + ] + ], +) -> None: + """This should help developers understand what failed""" + info = [f"Locating template {template!r}:"] + total_found = 0 + blueprint = None + if request_ctx and request_ctx.request.blueprint is not None: + blueprint = request_ctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, App): + src_info = f"application {srcobj.import_name!r}" + elif isinstance(srcobj, Blueprint): + src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})" + else: + src_info = repr(srcobj) + + info.append(f"{idx + 1:5}: trying loader of {src_info}") + + for line in _dump_loader_info(loader): + info.append(f" {line}") + + if triple is None: + detail = "no match" + else: + detail = f"found ({triple[1] or ''!r})" + total_found += 1 + info.append(f" -> {detail}") + + seems_fishy = False + if total_found == 0: + info.append("Error: the template could not be found.") + seems_fishy = True + elif total_found > 1: + info.append("Warning: multiple loaders returned a match for the template.") + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append( + " The template was looked up from an endpoint that belongs" + f" to the blueprint {blueprint!r}." + ) + info.append(" Maybe you did not place a template in the right folder?") + info.append(" See https://flask.palletsprojects.com/blueprints/#templates") + + app.logger.info("\n".join(info)) diff --git a/.venv/lib/python3.11/site-packages/flask/globals.py b/.venv/lib/python3.11/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/globals.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +import typing as t +from contextvars import ContextVar + +from werkzeug.local import LocalProxy + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .ctx import _AppCtxGlobals + from .ctx import AppContext + from .ctx import RequestContext + from .sessions import SessionMixin + from .wrappers import Request + + +_no_app_msg = """\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +the current application. To solve this, set up an application context +with app.app_context(). See the documentation for more information.\ +""" +_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx") +app_ctx: AppContext = LocalProxy( # type: ignore[assignment] + _cv_app, unbound_message=_no_app_msg +) +current_app: Flask = LocalProxy( # type: ignore[assignment] + _cv_app, "app", unbound_message=_no_app_msg +) +g: _AppCtxGlobals = LocalProxy( # type: ignore[assignment] + _cv_app, "g", unbound_message=_no_app_msg +) + +_no_req_msg = """\ +Working outside of request context. + +This typically means that you attempted to use functionality that needed +an active HTTP request. Consult the documentation on testing for +information about how to avoid this problem.\ +""" +_cv_request: ContextVar[RequestContext] = ContextVar("flask.request_ctx") +request_ctx: RequestContext = LocalProxy( # type: ignore[assignment] + _cv_request, unbound_message=_no_req_msg +) +request: Request = LocalProxy( # type: ignore[assignment] + _cv_request, "request", unbound_message=_no_req_msg +) +session: SessionMixin = LocalProxy( # type: ignore[assignment] + _cv_request, "session", unbound_message=_no_req_msg +) diff --git a/.venv/lib/python3.11/site-packages/flask/helpers.py b/.venv/lib/python3.11/site-packages/flask/helpers.py new file mode 100644 index 0000000..a6b7e15 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/helpers.py @@ -0,0 +1,634 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import cache +from functools import update_wrapper + +import werkzeug.utils +from werkzeug.exceptions import abort as _wz_abort +from werkzeug.utils import redirect as _wz_redirect +from werkzeug.wrappers import Response as BaseResponse + +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .globals import request_ctx +from .globals import session +from .signals import message_flashed + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +def get_debug_flag() -> bool: + """Get whether debug mode should be enabled for the app, indicated by the + :envvar:`FLASK_DEBUG` environment variable. The default is ``False``. + """ + val = os.environ.get("FLASK_DEBUG") + return bool(val and val.lower() not in {"0", "false", "no"}) + + +def get_load_dotenv(default: bool = True) -> bool: + """Get whether the user has disabled loading default dotenv files by + setting :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load + the files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get("FLASK_SKIP_DOTENV") + + if not val: + return default + + return val.lower() in ("0", "false", "no") + + +@t.overload +def stream_with_context( + generator_or_function: t.Iterator[t.AnyStr], +) -> t.Iterator[t.AnyStr]: ... + + +@t.overload +def stream_with_context( + generator_or_function: t.Callable[..., t.Iterator[t.AnyStr]], +) -> t.Callable[[t.Iterator[t.AnyStr]], t.Iterator[t.AnyStr]]: ... + + +def stream_with_context( + generator_or_function: t.Iterator[t.AnyStr] | t.Callable[..., t.Iterator[t.AnyStr]], +) -> t.Iterator[t.AnyStr] | t.Callable[[t.Iterator[t.AnyStr]], t.Iterator[t.AnyStr]]: + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) # type: ignore[arg-type] + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore[operator] + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore[arg-type] + + def generator() -> t.Iterator[t.AnyStr | None]: + ctx = _cv_request.get(None) + if ctx is None: + raise RuntimeError( + "'stream_with_context' can only be used when a request" + " context is active, such as in a view function." + ) + with ctx: + # Dummy sentinel. Has to be inside the context block or we're + # not actually keeping the context around. + yield None + + # The try/finally is here so that if someone passes a WSGI level + # iterator in we're still running the cleanup logic. Generators + # don't need that because they are closed on their destruction + # automatically. + try: + yield from gen + finally: + if hasattr(gen, "close"): + gen.close() + + # The trick is to start the generator. Then the code execution runs until + # the first dummy None is yielded at which point the context was already + # pushed. This item is discarded. Then when the iteration continues the + # real generator is executed. + wrapped_g = generator() + next(wrapped_g) + return wrapped_g # type: ignore[return-value] + + +def make_response(*args: t.Any) -> Response: + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) + + +def url_for( + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, +) -> str: + """Generate a URL to the given endpoint with the given values. + + This requires an active request or application context, and calls + :meth:`current_app.url_for() `. See that method + for full documentation. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it is + external. + :param _external: If given, prefer the URL to be internal (False) or + require it to be external (True). External URLs include the + scheme and domain. When not in an active request, URLs are + external by default. + :param values: Values to use for the variable parts of the URL rule. + Unknown keys are appended as query string arguments, like + ``?a=b&c=d``. + + .. versionchanged:: 2.2 + Calls ``current_app.url_for``, allowing an app to override the + behavior. + + .. versionchanged:: 0.10 + The ``_scheme`` parameter was added. + + .. versionchanged:: 0.9 + The ``_anchor`` and ``_method`` parameters were added. + + .. versionchanged:: 0.9 + Calls ``app.handle_url_build_error`` on build errors. + """ + return current_app.url_for( + endpoint, + _anchor=_anchor, + _method=_method, + _scheme=_scheme, + _external=_external, + **values, + ) + + +def redirect( + location: str, code: int = 302, Response: type[BaseResponse] | None = None +) -> BaseResponse: + """Create a redirect response object. + + If :data:`~flask.current_app` is available, it will use its + :meth:`~flask.Flask.redirect` method, otherwise it will use + :func:`werkzeug.utils.redirect`. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + :param Response: The response class to use. Not used when + ``current_app`` is active, which uses ``app.response_class``. + + .. versionadded:: 2.2 + Calls ``current_app.redirect`` if available instead of always + using Werkzeug's default ``redirect``. + """ + if current_app: + return current_app.redirect(location, code=code) + + return _wz_redirect(location, code=code, Response=Response) + + +def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given + status code. + + If :data:`~flask.current_app` is available, it will call its + :attr:`~flask.Flask.aborter` object, otherwise it will use + :func:`werkzeug.exceptions.abort`. + + :param code: The status code for the exception, which must be + registered in ``app.aborter``. + :param args: Passed to the exception. + :param kwargs: Passed to the exception. + + .. versionadded:: 2.2 + Calls ``current_app.aborter`` if available instead of always + using Werkzeug's default ``abort``. + """ + if current_app: + current_app.aborter(code, *args, **kwargs) + + _wz_abort(code, *args, **kwargs) + + +def get_template_attribute(template_name: str, attribute: str) -> t.Any: + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, attribute) + + +def flash(message: str, category: str = "message") -> None: + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get("_flashes", []) + flashes.append((category, message)) + session["_flashes"] = flashes + app = current_app._get_current_object() # type: ignore + message_flashed.send( + app, + _async_wrapper=app.ensure_sync, + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> list[str] | list[tuple[str, str]]: + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :doc:`/patterns/flashing` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: filter of categories to limit return values. Only + categories in the list will be returned. + """ + flashes = request_ctx.flashes + if flashes is None: + flashes = session.pop("_flashes") if "_flashes" in session else [] + request_ctx.flashes = flashes + if category_filter: + flashes = list(filter(lambda f: f[0] in category_filter, flashes)) + if not with_categories: + return [x[1] for x in flashes] + return flashes + + +def _prepare_send_file_kwargs(**kwargs: t.Any) -> dict[str, t.Any]: + if kwargs.get("max_age") is None: + kwargs["max_age"] = current_app.get_send_file_max_age + + kwargs.update( + environ=request.environ, + use_x_sendfile=current_app.config["USE_X_SENDFILE"], + response_class=current_app.response_class, + _root_path=current_app.root_path, # type: ignore + ) + return kwargs + + +def send_file( + path_or_file: os.PathLike[t.AnyStr] | str | t.BinaryIO, + mimetype: str | None = None, + as_attachment: bool = False, + download_name: str | None = None, + conditional: bool = True, + etag: bool | str = True, + last_modified: datetime | int | float | None = None, + max_age: None | (int | t.Callable[[str | None], int | None]) = None, +) -> Response: + """Send the contents of a file to the client. + + The first argument can be a file path or a file-like object. Paths + are preferred in most cases because Werkzeug can manage the file and + get extra information from the path. Passing a file-like object + requires that the file is opened in binary mode, and is mostly + useful when building a file in memory with :class:`io.BytesIO`. + + Never pass file paths provided by a user. The path is assumed to be + trusted, so a user could craft a path to access a file you didn't + intend. Use :func:`send_from_directory` to safely serve + user-requested paths from within a directory. + + If the WSGI server sets a ``file_wrapper`` in ``environ``, it is + used, otherwise Werkzeug's built-in wrapper is used. Alternatively, + if the HTTP server supports ``X-Sendfile``, configuring Flask with + ``USE_X_SENDFILE = True`` will tell the server to send the given + path, which is much more efficient than reading it in Python. + + :param path_or_file: The path to the file to send, relative to the + current working directory if a relative path is given. + Alternatively, a file-like object opened in binary mode. Make + sure the file pointer is seeked to the start of the data. + :param mimetype: The MIME type to send for the file. If not + provided, it will try to detect it from the file name. + :param as_attachment: Indicate to a browser that it should offer to + save the file instead of displaying it. + :param download_name: The default name browsers will use when saving + the file. Defaults to the passed file name. + :param conditional: Enable conditional and range responses based on + request headers. Requires passing a file path and ``environ``. + :param etag: Calculate an ETag for the file, which requires passing + a file path. Can also be a string to use instead. + :param last_modified: The last modified time to send for the file, + in seconds. If not provided, it will try to detect it from the + file path. + :param max_age: How long the client should cache the file, in + seconds. If set, ``Cache-Control`` will be ``public``, otherwise + it will be ``no-cache`` to prefer conditional caching. + + .. versionchanged:: 2.0 + ``download_name`` replaces the ``attachment_filename`` + parameter. If ``as_attachment=False``, it is passed with + ``Content-Disposition: inline`` instead. + + .. versionchanged:: 2.0 + ``max_age`` replaces the ``cache_timeout`` parameter. + ``conditional`` is enabled and ``max_age`` is not set by + default. + + .. versionchanged:: 2.0 + ``etag`` replaces the ``add_etags`` parameter. It can be a + string to use instead of generating one. + + .. versionchanged:: 2.0 + Passing a file-like object that inherits from + :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather + than sending an empty file. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionchanged:: 1.1 + ``filename`` may be a :class:`~os.PathLike` object. + + .. versionchanged:: 1.1 + Passing a :class:`~io.BytesIO` object supports range requests. + + .. versionchanged:: 1.0.3 + Filenames are encoded with ASCII instead of Latin-1 for broader + compatibility with WSGI servers. + + .. versionchanged:: 1.0 + UTF-8 filenames as specified in :rfc:`2231` are supported. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file + objects. If you want to use automatic MIME and etag support, + pass a filename via ``filename_or_fp`` or + ``attachment_filename``. + + .. versionchanged:: 0.12 + ``attachment_filename`` is preferred over ``filename`` for MIME + detection. + + .. versionchanged:: 0.9 + ``cache_timeout`` defaults to + :meth:`Flask.get_send_file_max_age`. + + .. versionchanged:: 0.7 + MIME guessing and etag support for file-like objects was + removed because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. + + .. versionchanged:: 0.5 + The ``add_etags``, ``cache_timeout`` and ``conditional`` + parameters were added. The default behavior is to add etags. + + .. versionadded:: 0.2 + """ + return werkzeug.utils.send_file( # type: ignore[return-value] + **_prepare_send_file_kwargs( + path_or_file=path_or_file, + environ=request.environ, + mimetype=mimetype, + as_attachment=as_attachment, + download_name=download_name, + conditional=conditional, + etag=etag, + last_modified=last_modified, + max_age=max_age, + ) + ) + + +def send_from_directory( + directory: os.PathLike[str] | str, + path: os.PathLike[str] | str, + **kwargs: t.Any, +) -> Response: + """Send a file from within a directory using :func:`send_file`. + + .. code-block:: python + + @app.route("/uploads/") + def download_file(name): + return send_from_directory( + app.config['UPLOAD_FOLDER'], name, as_attachment=True + ) + + This is a secure way to serve files from a folder, such as static + files or uploads. Uses :func:`~werkzeug.security.safe_join` to + ensure the path coming from the client is not maliciously crafted to + point outside the specified directory. + + If the final path does not point to an existing regular file, + raises a 404 :exc:`~werkzeug.exceptions.NotFound` error. + + :param directory: The directory that ``path`` must be located under, + relative to the current application's root path. This *must not* + be a value provided by the client, otherwise it becomes insecure. + :param path: The path to the file to send, relative to + ``directory``. + :param kwargs: Arguments to pass to :func:`send_file`. + + .. versionchanged:: 2.0 + ``path`` replaces the ``filename`` parameter. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionadded:: 0.5 + """ + return werkzeug.utils.send_from_directory( # type: ignore[return-value] + directory, path, **_prepare_send_file_kwargs(**kwargs) + ) + + +def get_root_path(import_name: str) -> str: + """Find the root path of a package, or the path that contains a + module. If it cannot be found, returns the current working + directory. + + Not to be confused with the value returned by :func:`find_package`. + + :meta private: + """ + # Module already imported and has a file attribute. Use that first. + mod = sys.modules.get(import_name) + + if mod is not None and hasattr(mod, "__file__") and mod.__file__ is not None: + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + try: + spec = importlib.util.find_spec(import_name) + + if spec is None: + raise ValueError + except (ImportError, ValueError): + loader = None + else: + loader = spec.loader + + # Loader does not exist or we're referring to an unloaded main + # module or a main module without path (interactive sessions), go + # with the current working directory. + if loader is None: + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) # pyright: ignore + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) # type: ignore[no-any-return] + + +@cache +def _split_blueprint_path(name: str) -> list[str]: + out: list[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/.venv/lib/python3.11/site-packages/flask/json/__init__.py b/.venv/lib/python3.11/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..c0941d0 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/json/__init__.py @@ -0,0 +1,170 @@ +from __future__ import annotations + +import json as _json +import typing as t + +from ..globals import current_app +from .provider import _default + +if t.TYPE_CHECKING: # pragma: no cover + from ..wrappers import Response + + +def dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dumps() ` + method, otherwise it will use :func:`json.dumps`. + + :param obj: The data to serialize. + :param kwargs: Arguments passed to the ``dumps`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dumps``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.dumps(obj, **kwargs) + + kwargs.setdefault("default", _default) + return _json.dumps(obj, **kwargs) + + +def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dump() ` + method, otherwise it will use :func:`json.dump`. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: Arguments passed to the ``dump`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dump``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, will be + removed in Flask 2.1. + """ + if current_app: + current_app.json.dump(obj, fp, **kwargs) + else: + kwargs.setdefault("default", _default) + _json.dump(obj, fp, **kwargs) + + +def loads(s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.loads() ` + method, otherwise it will use :func:`json.loads`. + + :param s: Text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``loads`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.loads``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The data must be a + string or UTF-8 bytes. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.loads(s, **kwargs) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.load() ` + method, otherwise it will use :func:`json.load`. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``load`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.load``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The file must be text + mode, or binary mode with UTF-8 bytes. + """ + if current_app: + return current_app.json.load(fp, **kwargs) + + return _json.load(fp, **kwargs) + + +def jsonify(*args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. A dict or list returned from a view will be converted to a + JSON response automatically without needing to call this. + + This requires an active request or application context, and calls + :meth:`app.json.response() `. + + In debug mode, the output is formatted with indentation to make it + easier to read. This may also be controlled by the provider. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + + .. versionchanged:: 2.2 + Calls ``current_app.json.response``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 0.11 + Added support for serializing top-level arrays. This was a + security risk in ancient browsers. See :ref:`security-json`. + + .. versionadded:: 0.2 + """ + return current_app.json.response(*args, **kwargs) # type: ignore[return-value] diff --git a/.venv/lib/python3.11/site-packages/flask/json/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/json/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..247b8bf2ad2fdcc7cf5ffa883bfd839431b9ee64 GIT binary patch literal 6869 zcmd5>O>Y~=8Q!HRX)RfnzrSNoVml}ec_quSQLu&^!yl~^)CnRrX;l>DkUNytUhXop zOR_A4qKBM{pztj^`jE6P`Vaamm_R@b0uGE8J@_WT=tZYK@67I!lqppqT~RLup`q@p28d{5aYOL7EXje6tN-3z<%)p2Lyv+TlzbHdq& z`yS_{a}f7Q=MCpD?t7h6&N1BgIhi>lclsF_$eEpS?)yQ+BRBBFyU(bD^s-!+QutAU z*J{s9{mv>lqQdK5gmUX65!O&abcTY`z4hV9zV5d=BlnwJE{2^EDWbacJ40b4%Tzo0 z4I?vd80Pa8WWF$>c9~%;8x_+vmd!8CKbv#7KOE|*o@O00veF0R zFR11r+o@M;;g53cs`MtBr&ee{C9%XCZXma8c*gEFoiAevg!!T)%5If=_Dy|P z>maPxYJrU4u2PGY10M}W)CV-q8MX)VTep*TtymO(IdD(`o>B{{BoZGn*JrnB9m2I2 zx3G87p6PLY;`TBe0$cI4I<6Gu$ZJh8$>9!(Nk+L8pVnRKZS1|YTNqO$eiyMyAZdIR zcd?Fom~Op@I-?0_j7Zx3oh+@#&ahfDov~0vak(6&(%}LX=Q45^o+NG7kajO)>+eqo zwP?C51&>6ddZ8&w({@AnjcLyvDe;>GFEjl_i-FW={jBAiy+X_{^mR) z1{40KG{oD{YH-$*7 z5QjA-=0UIWitCAZO@1G+xoy;ZCD42|%&gRamy8C^f|~HL`)PZSPt@MWezDoyQc(9C zbt(|*{Br*Gg&(K8D%tAfL2S(i4k9N$e+V>V1m7Mszt+gS^T3??@RP*d1hpmC=dz`y z1SbI&DEYh(Qo&r*`8Jh+YicMyh&F&M&4Zl8hP|89&?fiNX3r9`$^FPGM3V=Q%MEEf zJ4|mCsA2OMRR18oIi4ib$b=OnKqFhBQFi$4C)R;g>*%WW#!C6&Y}=Z__2{s^r|DB` z&$rgGZ>(c0xvzfpwPmkbcH6R_SQDR*J-D=zX4Nx;6Rij_rZbIr7Z%jS$igh zn3n`9#TpZ!qR=WeR1F-+2{(wS2vsrI(!!@8Fa$Cq3`7K1 zSMhL4ZPiY$LQZv|n(6WoLr!;lL{bN>WUiMNyph%&NEGM071X-yub}J>Vl=ZoO4g<# zS~Al+AFlPZp6tz?*U@I645f~}?l@RCu`s6s^Te;}5DjVSVOHjAy{6DO1>DzA73CDD%mOBnc&nNh@y$2h+vW6 zQS&`3aXcikx9Dw;B&LwNGfGz7N=u$Y@t^P)67>V)d)G8}A6Xqgu{wVCq0=6}{0Oqt zWxBGL6`w=Yszf&WXM!>-Rc<#uk}Q_9ddk(Qab&=kN9oHE%|uTQC?}gJSM^VCUarPA zs3&xE>MTb`S z9g?*n(=;C&Z?*fcr^dl{ay>Tox0CCs@n*aKdTg9(_g_zkvY-7FVx)QYarO)tc<;3~ pa@u@*&FD{VnkVRGe{%Jtd3Md{Pp+Mycm2s#W?oq{Hc8a@{|hykh@1cb literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/json/__pycache__/provider.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/json/__pycache__/provider.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bed01db1f4b6114bbe3e27e7374dd9a6d8c9a644 GIT binary patch literal 9984 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 K-ld(f$bSQ%DeBe$ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/json/__pycache__/tag.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/json/__pycache__/tag.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87b4e379bfc3d90a3d10de42490dcaa918369d09 GIT binary patch literal 16577 zcmd5@ZEPIJdEUJb^6vPtq)1A%M2RbjB6YHKjBCZUX<3dWN`YLPPEENiyyxxx>!jEN;-UxIVr4SQ_STKOPYsR>@qLPf>583GW@a>1 zeqsFOvDmfR6^osaQ~B(yk}_poo7FW#%bALq&gbOmye?<*hLO<>LpC%$tz^znh5i|2nXBu)e+_4s9RWX&r@>Ic;)25tN=H)4k9-A&?+lQMt?-%~K5;Jz;QIHu6NhiW7v^g0~prs)>uMSO4g4nUN3QkH-&$Ajt>x6vHHJdg=(WL2lOd2tO%Ema2 z?oBqDbPm;OeVEFO4C+yr(|SI~u%{bN1|ywIX~4lvwn;f#Fw7YE!0to^Q-I=Bk$Rh) zOt9%prfPdlr}Nd+!&b$`&R z5g%byh>4O(Ba=6cWKw=kJ~&h(!qDNkQ-?_ToXkkcai9lPZCXxU)KZrY8d_%Bnk`qu zR7cm$f}WGppah9#N;}Br^swy0Dei63%qMABk8bq*`Ae7*bPb8-szB3;7zZ!MFECYs z;>*N};4qzW8SgxP!Pg-t@1whPVQsa=n^IABscRCIOJypB% z+$Z9(_sIan#cGR^%jLPgGsbR<)#%hyM^%lO0fls<<*b_s)Q@JSvl?oJUVZiKDE^yX zQuIrOS$giGY0f683T_}kx}mYV_sI^$#cG%Y(4a&nuc$_f+aC@sb0lt!;r^DO2@@g= zYT#9v(TSiMfEf)=gw>GNq=t{7hT5&hUJp$)t35Dxp^1pPU6t@3#eWC>W9kld8~$6= zE-3%rYO}?I#nF?Bp~;+0NwtHa(z$eQMkd*mF_Q+HMq3ksbg&on@VGPIlL;DKZT_o5 zHE5W6H3*K?w*$9occaIuO`I{Sp|N~UOF5<)4^SH87q_~RxFsxz3qlepeyJix5Gck^ z=^6+NjRhoUpf3n}5_?iXxtg)i6JvT0o{R^oA!1a9kwHDk^8GWz`B`%~#ag5?vYM3+RlZhvu7&gGVM_>&vDKnZe%;bKU1Y{U}CuZlXktA3yZ6=e&4vVk} zJLfcdGTHzZg^is9OQB_H37;)w2-PqX#QR}0aUwTg4Nc|q84n%cMsYfHAaP4D=^^X- zq8Jy8Pn{ysm($a(fwLxM<6^#$A*IHtgA{38sD45i)73SWH_wvg$wD1#>S

  • $d~? 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/json/provider.py b/.venv/lib/python3.11/site-packages/flask/json/provider.py new file mode 100644 index 0000000..ea7e475 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/json/provider.py @@ -0,0 +1,215 @@ +from __future__ import annotations + +import dataclasses +import decimal +import json +import typing as t +import uuid +import weakref +from datetime import date + +from werkzeug.http import http_date + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.sansio.response import Response + + from ..sansio.app import App + + +class JSONProvider: + """A standard set of JSON operations for an application. Subclasses + of this can be used to customize JSON behavior or use different + JSON libraries. + + To implement a provider for a specific library, subclass this base + class and implement at least :meth:`dumps` and :meth:`loads`. All + other methods have default implementations. + + To use a different provider, either subclass ``Flask`` and set + :attr:`~flask.Flask.json_provider_class` to a provider class, or set + :attr:`app.json ` to an instance of the class. + + :param app: An application instance. This will be stored as a + :class:`weakref.proxy` on the :attr:`_app` attribute. + + .. versionadded:: 2.2 + """ + + def __init__(self, app: App) -> None: + self._app: App = weakref.proxy(app) + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + :param obj: The data to serialize. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def dump(self, obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: May be passed to the underlying JSON library. + """ + fp.write(self.dumps(obj, **kwargs)) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + :param s: Text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + return self.loads(fp.read(), **kwargs) + + def _prepare_response_obj( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> t.Any: + if args and kwargs: + raise TypeError("app.json.response() takes either args or kwargs, not both") + + if not args and not kwargs: + return None + + if len(args) == 1: + return args[0] + + return args or kwargs + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. + + The :func:`~flask.json.jsonify` function calls this method for + the current application. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + return self._app.response_class(self.dumps(obj), mimetype="application/json") + + +def _default(o: t.Any) -> t.Any: + if isinstance(o, date): + return http_date(o) + + if isinstance(o, (decimal.Decimal, uuid.UUID)): + return str(o) + + if dataclasses and dataclasses.is_dataclass(o): + return dataclasses.asdict(o) # type: ignore[arg-type] + + if hasattr(o, "__html__"): + return str(o.__html__()) + + raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable") + + +class DefaultJSONProvider(JSONProvider): + """Provide JSON operations using Python's built-in :mod:`json` + library. Serializes the following additional data types: + + - :class:`datetime.datetime` and :class:`datetime.date` are + serialized to :rfc:`822` strings. This is the same as the HTTP + date format. + - :class:`uuid.UUID` is serialized to a string. + - :class:`dataclasses.dataclass` is passed to + :func:`dataclasses.asdict`. + - :class:`~markupsafe.Markup` (or any object with a ``__html__`` + method) will call the ``__html__`` method to get a string. + """ + + default: t.Callable[[t.Any], t.Any] = staticmethod(_default) # type: ignore[assignment] + """Apply this function to any object that :meth:`json.dumps` does + not know how to serialize. It should return a valid JSON type or + raise a ``TypeError``. + """ + + ensure_ascii = True + """Replace non-ASCII characters with escape sequences. This may be + more compatible with some clients, but can be disabled for better + performance and size. + """ + + sort_keys = True + """Sort the keys in any serialized dicts. This may be useful for + some caching situations, but can be disabled for better performance. + When enabled, keys must all be strings, they are not converted + before sorting. + """ + + compact: bool | None = None + """If ``True``, or ``None`` out of debug mode, the :meth:`response` + output will not add indentation, newlines, or spaces. If ``False``, + or ``None`` in debug mode, it will use a non-compact representation. + """ + + mimetype = "application/json" + """The mimetype set in :meth:`response`.""" + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON to a string. + + Keyword arguments are passed to :func:`json.dumps`. Sets some + parameter defaults from the :attr:`default`, + :attr:`ensure_ascii`, and :attr:`sort_keys` attributes. + + :param obj: The data to serialize. + :param kwargs: Passed to :func:`json.dumps`. + """ + kwargs.setdefault("default", self.default) + kwargs.setdefault("ensure_ascii", self.ensure_ascii) + kwargs.setdefault("sort_keys", self.sort_keys) + return json.dumps(obj, **kwargs) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON from a string or bytes. + + :param s: Text or UTF-8 bytes. + :param kwargs: Passed to :func:`json.loads`. + """ + return json.loads(s, **kwargs) + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with it. The response mimetype + will be "application/json" and can be changed with + :attr:`mimetype`. + + If :attr:`compact` is ``False`` or debug mode is enabled, the + output will be formatted to be easier to read. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + dump_args: dict[str, t.Any] = {} + + if (self.compact is None and self._app.debug) or self.compact is False: + dump_args.setdefault("indent", 2) + else: + dump_args.setdefault("separators", (",", ":")) + + return self._app.response_class( + f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype + ) diff --git a/.venv/lib/python3.11/site-packages/flask/json/tag.py b/.venv/lib/python3.11/site-packages/flask/json/tag.py new file mode 100644 index 0000000..8dc3629 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/json/tag.py @@ -0,0 +1,327 @@ +""" +Tagged JSON +~~~~~~~~~~~ + +A compact representation for lossless serialization of non-standard JSON +types. :class:`~flask.sessions.SecureCookieSessionInterface` uses this +to serialize the session data, but it may be useful in other places. It +can be extended to support other types. + +.. autoclass:: TaggedJSONSerializer + :members: + +.. autoclass:: JSONTag + :members: + +Let's see an example that adds support for +:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so +to handle this we will dump the items as a list of ``[key, value]`` +pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to +identify the type. The session serializer processes dicts first, so +insert the new tag at the front of the order since ``OrderedDict`` must +be processed before ``dict``. + +.. code-block:: python + + from flask.json.tag import JSONTag + + class TagOrderedDict(JSONTag): + __slots__ = ('serializer',) + key = ' od' + + def check(self, value): + return isinstance(value, OrderedDict) + + def to_json(self, value): + return [[k, self.serializer.tag(v)] for k, v in iteritems(value)] + + def to_python(self, value): + return OrderedDict(value) + + app.session_interface.serializer.register(TagOrderedDict, index=0) +""" + +from __future__ import annotations + +import typing as t +from base64 import b64decode +from base64 import b64encode +from datetime import datetime +from uuid import UUID + +from markupsafe import Markup +from werkzeug.http import http_date +from werkzeug.http import parse_date + +from ..json import dumps +from ..json import loads + + +class JSONTag: + """Base class for defining type tags for :class:`TaggedJSONSerializer`.""" + + __slots__ = ("serializer",) + + #: The tag to mark the serialized object with. If empty, this tag is + #: only used as an intermediate step during tagging. + key: str = "" + + def __init__(self, serializer: TaggedJSONSerializer) -> None: + """Create a tagger for the given serializer.""" + self.serializer = serializer + + def check(self, value: t.Any) -> bool: + """Check if the given value should be tagged by this tag.""" + raise NotImplementedError + + def to_json(self, value: t.Any) -> t.Any: + """Convert the Python object to an object that is a valid JSON type. + The tag will be added later.""" + raise NotImplementedError + + def to_python(self, value: t.Any) -> t.Any: + """Convert the JSON representation back to the correct type. The tag + will already be removed.""" + raise NotImplementedError + + def tag(self, value: t.Any) -> dict[str, t.Any]: + """Convert the value to a valid JSON type and add the tag structure + around it.""" + return {self.key: self.to_json(value)} + + +class TagDict(JSONTag): + """Tag for 1-item dicts whose only key matches a registered tag. + + Internally, the dict key is suffixed with `__`, and the suffix is removed + when deserializing. + """ + + __slots__ = () + key = " di" + + def check(self, value: t.Any) -> bool: + return ( + isinstance(value, dict) + and len(value) == 1 + and next(iter(value)) in self.serializer.tags + ) + + def to_json(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {f"{key}__": self.serializer.tag(value[key])} + + def to_python(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {key[:-2]: value[key]} + + +class PassDict(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, dict) + + def to_json(self, value: t.Any) -> t.Any: + # JSON objects may only have string keys, so don't bother tagging the + # key here. + return {k: self.serializer.tag(v) for k, v in value.items()} + + tag = to_json + + +class TagTuple(JSONTag): + __slots__ = () + key = " t" + + def check(self, value: t.Any) -> bool: + return isinstance(value, tuple) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + def to_python(self, value: t.Any) -> t.Any: + return tuple(value) + + +class PassList(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, list) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + tag = to_json + + +class TagBytes(JSONTag): + __slots__ = () + key = " b" + + def check(self, value: t.Any) -> bool: + return isinstance(value, bytes) + + def to_json(self, value: t.Any) -> t.Any: + return b64encode(value).decode("ascii") + + def to_python(self, value: t.Any) -> t.Any: + return b64decode(value) + + +class TagMarkup(JSONTag): + """Serialize anything matching the :class:`~markupsafe.Markup` API by + having a ``__html__`` method to the result of that method. Always + deserializes to an instance of :class:`~markupsafe.Markup`.""" + + __slots__ = () + key = " m" + + def check(self, value: t.Any) -> bool: + return callable(getattr(value, "__html__", None)) + + def to_json(self, value: t.Any) -> t.Any: + return str(value.__html__()) + + def to_python(self, value: t.Any) -> t.Any: + return Markup(value) + + +class TagUUID(JSONTag): + __slots__ = () + key = " u" + + def check(self, value: t.Any) -> bool: + return isinstance(value, UUID) + + def to_json(self, value: t.Any) -> t.Any: + return value.hex + + def to_python(self, value: t.Any) -> t.Any: + return UUID(value) + + +class TagDateTime(JSONTag): + __slots__ = () + key = " d" + + def check(self, value: t.Any) -> bool: + return isinstance(value, datetime) + + def to_json(self, value: t.Any) -> t.Any: + return http_date(value) + + def to_python(self, value: t.Any) -> t.Any: + return parse_date(value) + + +class TaggedJSONSerializer: + """Serializer that uses a tag system to compactly represent objects that + are not JSON types. Passed as the intermediate serializer to + :class:`itsdangerous.Serializer`. + + The following extra types are supported: + + * :class:`dict` + * :class:`tuple` + * :class:`bytes` + * :class:`~markupsafe.Markup` + * :class:`~uuid.UUID` + * :class:`~datetime.datetime` + """ + + __slots__ = ("tags", "order") + + #: Tag classes to bind when creating the serializer. Other tags can be + #: added later using :meth:`~register`. + default_tags = [ + TagDict, + PassDict, + TagTuple, + PassList, + TagBytes, + TagMarkup, + TagUUID, + TagDateTime, + ] + + def __init__(self) -> None: + self.tags: dict[str, JSONTag] = {} + self.order: list[JSONTag] = [] + + for cls in self.default_tags: + self.register(cls) + + def register( + self, + tag_class: type[JSONTag], + force: bool = False, + index: int | None = None, + ) -> None: + """Register a new tag with this serializer. + + :param tag_class: tag class to register. Will be instantiated with this + serializer instance. + :param force: overwrite an existing tag. If false (default), a + :exc:`KeyError` is raised. + :param index: index to insert the new tag in the tag order. Useful when + the new tag is a special case of an existing tag. If ``None`` + (default), the tag is appended to the end of the order. + + :raise KeyError: if the tag key is already registered and ``force`` is + not true. + """ + tag = tag_class(self) + key = tag.key + + if key: + if not force and key in self.tags: + raise KeyError(f"Tag '{key}' is already registered.") + + self.tags[key] = tag + + if index is None: + self.order.append(tag) + else: + self.order.insert(index, tag) + + def tag(self, value: t.Any) -> t.Any: + """Convert a value to a tagged representation if necessary.""" + for tag in self.order: + if tag.check(value): + return tag.tag(value) + + return value + + def untag(self, value: dict[str, t.Any]) -> t.Any: + """Convert a tagged representation back to the original type.""" + if len(value) != 1: + return value + + key = next(iter(value)) + + if key not in self.tags: + return value + + return self.tags[key].to_python(value[key]) + + def _untag_scan(self, value: t.Any) -> t.Any: + if isinstance(value, dict): + # untag each item recursively + value = {k: self._untag_scan(v) for k, v in value.items()} + # untag the dict itself + value = self.untag(value) + elif isinstance(value, list): + # untag each item recursively + value = [self._untag_scan(item) for item in value] + + return value + + def dumps(self, value: t.Any) -> str: + """Tag the value and dump it to a compact JSON string.""" + return dumps(self.tag(value), separators=(",", ":")) + + def loads(self, value: str) -> t.Any: + """Load data from a JSON string and deserialized any tagged objects.""" + return self._untag_scan(loads(value)) diff --git a/.venv/lib/python3.11/site-packages/flask/logging.py b/.venv/lib/python3.11/site-packages/flask/logging.py new file mode 100644 index 0000000..0cb8f43 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/logging.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +import logging +import sys +import typing as t + +from werkzeug.local import LocalProxy + +from .globals import request + +if t.TYPE_CHECKING: # pragma: no cover + from .sansio.app import App + + +@LocalProxy +def wsgi_errors_stream() -> t.TextIO: + """Find the most appropriate error stream for the application. If a request + is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``. + + If you configure your own :class:`logging.StreamHandler`, you may want to + use this for the stream. If you are using file or dict configuration and + can't import this directly, you can refer to it as + ``ext://flask.logging.wsgi_errors_stream``. + """ + if request: + return request.environ["wsgi.errors"] # type: ignore[no-any-return] + + return sys.stderr + + +def has_level_handler(logger: logging.Logger) -> bool: + """Check if there is a handler in the logging chain that will handle the + given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`. + """ + level = logger.getEffectiveLevel() + current = logger + + while current: + if any(handler.level <= level for handler in current.handlers): + return True + + if not current.propagate: + break + + current = current.parent # type: ignore + + return False + + +#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format +#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``. +default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore +default_handler.setFormatter( + logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s") +) + + +def create_logger(app: App) -> logging.Logger: + """Get the Flask app's logger and configure it if needed. + + The logger name will be the same as + :attr:`app.import_name `. + + When :attr:`~flask.Flask.debug` is enabled, set the logger level to + :data:`logging.DEBUG` if it is not set. + + If there is no handler for the logger's effective level, add a + :class:`~logging.StreamHandler` for + :func:`~flask.logging.wsgi_errors_stream` with a basic format. + """ + logger = logging.getLogger(app.name) + + if app.debug and not logger.level: + logger.setLevel(logging.DEBUG) + + if not has_level_handler(logger): + logger.addHandler(default_handler) + + return logger diff --git a/.venv/lib/python3.11/site-packages/flask/py.typed b/.venv/lib/python3.11/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.11/site-packages/flask/sansio/README.md b/.venv/lib/python3.11/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/sansio/README.md @@ -0,0 +1,6 @@ +# Sansio + +This folder contains code that can be used by alternative Flask +implementations, for example Quart. The code therefore cannot do any +IO, nor be part of a likely IO path. Finally this code cannot use the +Flask globals. diff --git a/.venv/lib/python3.11/site-packages/flask/sansio/__pycache__/app.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/sansio/__pycache__/app.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c07aa49a2ef1438c1b9684f2e1f70df3c6864e0d GIT binary patch literal 35436 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/sansio/__pycache__/blueprints.cpython-311.pyc b/.venv/lib/python3.11/site-packages/flask/sansio/__pycache__/blueprints.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40c96534870c0192769582c655d198fbe64d25c6 GIT binary patch literal 32545 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 M?4*S2I81{5|A3wno&W#< literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/flask/sansio/app.py b/.venv/lib/python3.11/site-packages/flask/sansio/app.py new file mode 100644 index 0000000..3620171 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/sansio/app.py @@ -0,0 +1,964 @@ +from __future__ import annotations + +import logging +import os +import sys +import typing as t +from datetime import timedelta +from itertools import chain + +from werkzeug.exceptions import Aborter +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.routing import BuildError +from werkzeug.routing import Map +from werkzeug.routing import Rule +from werkzeug.sansio.response import Response +from werkzeug.utils import cached_property +from werkzeug.utils import redirect as _wz_redirect + +from .. import typing as ft +from ..config import Config +from ..config import ConfigAttribute +from ..ctx import _AppCtxGlobals +from ..helpers import _split_blueprint_path +from ..helpers import get_debug_flag +from ..json.provider import DefaultJSONProvider +from ..json.provider import JSONProvider +from ..logging import create_logger +from ..templating import DispatchingJinjaLoader +from ..templating import Environment +from .scaffold import _endpoint_from_view_func +from .scaffold import find_package +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.wrappers import Response as BaseResponse + + from ..testing import FlaskClient + from ..testing import FlaskCliRunner + from .blueprints import Blueprint + +T_shell_context_processor = t.TypeVar( + "T_shell_context_processor", bound=ft.ShellContextProcessorCallable +) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) + + +def _make_timedelta(value: timedelta | int | None) -> timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class App(Scaffold): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + #: The class of the object assigned to :attr:`aborter`, created by + #: :meth:`create_aborter`. That object is called by + #: :func:`flask.abort` to raise HTTP errors, and can be + #: called directly as well. + #: + #: Defaults to :class:`werkzeug.exceptions.Aborter`. + #: + #: .. versionadded:: 2.2 + aborter_class = Aborter + + #: The class that is used for the Jinja environment. + #: + #: .. versionadded:: 0.11 + jinja_environment = Environment + + #: The class that is used for the :data:`~flask.g` instance. + #: + #: Example use cases for a custom class: + #: + #: 1. Store arbitrary attributes on flask.g. + #: 2. Add a property for lazy per-request database connectors. + #: 3. Return None instead of AttributeError on unexpected attributes. + #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. + #: + #: In Flask 0.9 this property was called `request_globals_class` but it + #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the + #: flask.g object is now application context scoped. + #: + #: .. versionadded:: 0.10 + app_ctx_globals_class = _AppCtxGlobals + + #: The class that is used for the ``config`` attribute of this app. + #: Defaults to :class:`~flask.Config`. + #: + #: Example use cases for a custom class: + #: + #: 1. Default values for certain config options. + #: 2. Access to config values through attributes in addition to keys. + #: + #: .. versionadded:: 0.11 + config_class = Config + + #: The testing flag. Set this to ``True`` to enable the test mode of + #: Flask extensions (and in the future probably also Flask itself). + #: For example this might activate test helpers that have an + #: additional runtime cost which should not be enabled by default. + #: + #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the + #: default it's implicitly enabled. + #: + #: This attribute can also be configured from the config with the + #: ``TESTING`` configuration key. Defaults to ``False``. + testing = ConfigAttribute[bool]("TESTING") + + #: If a secret key is set, cryptographic components can use this to + #: sign cookies and other things. Set this to a complex random value + #: when you want to use the secure cookie for instance. + #: + #: This attribute can also be configured from the config with the + #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. + secret_key = ConfigAttribute[t.Union[str, bytes, None]]("SECRET_KEY") + + #: A :class:`~datetime.timedelta` which is used to set the expiration + #: date of a permanent session. The default is 31 days which makes a + #: permanent session survive for roughly one month. + #: + #: This attribute can also be configured from the config with the + #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to + #: ``timedelta(days=31)`` + permanent_session_lifetime = ConfigAttribute[timedelta]( + "PERMANENT_SESSION_LIFETIME", + get_converter=_make_timedelta, # type: ignore[arg-type] + ) + + json_provider_class: type[JSONProvider] = DefaultJSONProvider + """A subclass of :class:`~flask.json.provider.JSONProvider`. An + instance is created and assigned to :attr:`app.json` when creating + the app. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses + Python's built-in :mod:`json` library. A different provider can use + a different JSON library. + + .. versionadded:: 2.2 + """ + + #: Options that are passed to the Jinja environment in + #: :meth:`create_jinja_environment`. Changing these options after + #: the environment is created (accessing :attr:`jinja_env`) will + #: have no effect. + #: + #: .. versionchanged:: 1.1.0 + #: This is a ``dict`` instead of an ``ImmutableDict`` to allow + #: easier configuration. + #: + jinja_options: dict[str, t.Any] = {} + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: The map object to use for storing the URL rules and routing + #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`. + #: + #: .. versionadded:: 1.1.0 + url_map_class = Map + + #: The :meth:`test_client` method creates an instance of this test + #: client class. Defaults to :class:`~flask.testing.FlaskClient`. + #: + #: .. versionadded:: 0.7 + test_client_class: type[FlaskClient] | None = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class: type[FlaskCliRunner] | None = None + + default_config: dict[str, t.Any] + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ) -> None: + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + "If an instance path is provided it must be absolute." + " A relative path was given instead." + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: An instance of :attr:`aborter_class` created by + #: :meth:`make_aborter`. This is called by :func:`flask.abort` + #: to raise HTTP errors, and can be called directly as well. + #: + #: .. versionadded:: 2.2 + #: Moved from ``flask.abort``, which calls this object. + self.aborter = self.make_aborter() + + self.json: JSONProvider = self.json_provider_class(self) + """Provides access to JSON methods. Functions in ``flask.json`` + will call methods on this provider when the application context + is active. Used for handling JSON requests and responses. + + An instance of :attr:`json_provider_class`. Can be customized by + changing that attribute on a subclass, or by assigning to this + attribute afterwards. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, + uses Python's built-in :mod:`json` library. A different provider + can use a different JSON library. + + .. versionadded:: 2.2 + """ + + #: A list of functions that are called by + #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function is called + #: with ``error``, ``endpoint`` and ``values``. If a function + #: returns ``None`` or raises a ``BuildError``, it is skipped. + #: Otherwise, its return value is returned by ``url_for``. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers: list[ + t.Callable[[Exception, str, dict[str, t.Any]], str] + ] = [] + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs: list[ft.TeardownCallable] = [] + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors: list[ft.ShellContextProcessorCallable] = [] + + #: Maps registered blueprint names to blueprint objects. The + #: dict retains the order the blueprints were registered in. + #: Blueprints can be registered multiple times, this dict does + #: not track how often they were attached. + #: + #: .. versionadded:: 0.7 + self.blueprints: dict[str, Blueprint] = {} + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions: dict[str, t.Any] = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = self.url_map_class(host_matching=host_matching) + + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_first_request: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called" + " on the application. It has already handled its first" + " request, any changes will not be applied" + " consistently.\n" + "Make sure all imports, decorators, functions, etc." + " needed to set up the application are done before" + " running it." + ) + + @cached_property + def name(self) -> str: # type: ignore + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == "__main__": + fn: str | None = getattr(sys.modules["__main__"], "__file__", None) + if fn is None: + return "__main__" + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @cached_property + def logger(self) -> logging.Logger: + """A standard Python :class:`~logging.Logger` for the app, with + the same name as :attr:`name`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will + be set to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be + added. See :doc:`/logging` for more information. + + .. versionchanged:: 1.1.0 + The logger takes the same name as :attr:`name` rather than + hard-coding ``"flask.app"``. + + .. versionchanged:: 1.0.0 + Behavior was simplified. The logger is always named + ``"flask.app"``. The level is only set during configuration, + it doesn't check ``app.debug`` each time. Only one format is + used, not different ones depending on ``app.debug``. No + handlers are removed, and a handler is only added if no + handlers are already configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @cached_property + def jinja_env(self) -> Environment: + """The Jinja environment used to load templates. + + The environment is created the first time this property is + accessed. Changing :attr:`jinja_options` after that will have no + effect. + """ + return self.create_jinja_environment() + + def create_jinja_environment(self) -> Environment: + raise NotImplementedError() + + def make_config(self, instance_relative: bool = False) -> Config: + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults["DEBUG"] = get_debug_flag() + return self.config_class(root_path, defaults) + + def make_aborter(self) -> Aborter: + """Create the object to assign to :attr:`aborter`. That object + is called by :func:`flask.abort` to raise HTTP errors, and can + be called directly as well. + + By default, this creates an instance of :attr:`aborter_class`, + which defaults to :class:`werkzeug.exceptions.Aborter`. + + .. versionadded:: 2.2 + """ + return self.aborter_class() + + def auto_find_instance_path(self) -> str: + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, "instance") + return os.path.join(prefix, "var", f"{self.name}-instance") + + def create_global_jinja_loader(self) -> DispatchingJinjaLoader: + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename: str) -> bool: + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionchanged:: 2.2 + Autoescaping is now enabled by default for ``.svg`` files. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml", ".svg")) + + @property + def debug(self) -> bool: + """Whether debug mode is enabled. When using ``flask run`` to start the + development server, an interactive debugger will be shown for unhandled + exceptions, and the server will be reloaded when code changes. This maps to the + :data:`DEBUG` config key. It may not behave as expected if set late. + + **Do not enable debug mode when deploying in production.** + + Default: ``False`` + """ + return self.config["DEBUG"] # type: ignore[no-any-return] + + @debug.setter + def debug(self, value: bool) -> None: + self.config["DEBUG"] = value + + if self.config["TEMPLATES_AUTO_RELOAD"] is None: + self.jinja_env.auto_reload = value + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 0.7 + """ + blueprint.register(self, options) + + def iter_blueprints(self) -> t.ValuesView[Blueprint]: + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return self.blueprints.values() + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + options["endpoint"] = endpoint + methods = options.pop("methods", None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, "methods", None) or ("GET",) + if isinstance(methods, str): + raise TypeError( + "Allowed methods must be a list of strings, for" + ' example: @app.route(..., methods=["POST"])' + ) + methods = {item.upper() for item in methods} + + # Methods that should always be added + required_methods: set[str] = set(getattr(view_func, "required_methods", ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr( + view_func, "provide_automatic_options", None + ) + + if provide_automatic_options is None: + if "OPTIONS" not in methods and self.config["PROVIDE_AUTOMATIC_OPTIONS"]: + provide_automatic_options = True + required_methods.add("OPTIONS") + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule_obj = self.url_rule_class(rule, methods=methods, **options) + rule_obj.provide_automatic_options = provide_automatic_options # type: ignore[attr-defined] + + self.url_map.add(rule_obj) + if view_func is not None: + old_func = self.view_functions.get(endpoint) + if old_func is not None and old_func != view_func: + raise AssertionError( + "View function mapping is overwriting an existing" + f" endpoint function: {endpoint}" + ) + self.view_functions[endpoint] = view_func + + @setupmethod + def template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """A decorator that is used to register custom template test. + You can specify a name for the test, otherwise the function + name will be used. Example:: + + @app.template_test() + def is_prime(n): + if n == 2: + return True + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): + if n % i == 0: + return False + return True + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def teardown_appcontext(self, f: T_teardown) -> T_teardown: + """Registers a function to be called when the application + context is popped. The application context is typically popped + after the request context for each request, at the end of CLI + commands, or after a manually pushed context ends. + + .. code-block:: python + + with app.app_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the app context is + made inactive. Since a request context typically also manages an + application context it would also be called when you pop a + request context. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + .. versionadded:: 0.9 + """ + self.teardown_appcontext_funcs.append(f) + return f + + @setupmethod + def shell_context_processor( + self, f: T_shell_context_processor + ) -> T_shell_context_processor: + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + def _find_error_handler( + self, e: Exception, blueprints: list[str] + ) -> ft.ErrorHandlerCallable | None: + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + names = (*blueprints, None) + + for c in (code, None) if code is not None else (None,): + for name in names: + handler_map = self.error_handler_spec[name][c] + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + return None + + def trap_http_exception(self, e: Exception) -> bool: + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config["TRAP_HTTP_EXCEPTIONS"]: + return True + + trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None + and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def should_ignore_error(self, error: BaseException | None) -> bool: + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def redirect(self, location: str, code: int = 302) -> BaseResponse: + """Create a redirect response object. + + This is called by :func:`flask.redirect`, and can be called + directly as well. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + + .. versionadded:: 2.2 + Moved from ``flask.redirect``, which calls this method. + """ + return _wz_redirect( + location, + code=code, + Response=self.response_class, # type: ignore[arg-type] + ) + + def inject_url_defaults(self, endpoint: str, values: dict[str, t.Any]) -> None: + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + names: t.Iterable[str | None] = (None,) + + # url_for may be called outside a request context, parse the + # passed endpoint instead of using request.blueprints. + if "." in endpoint: + names = chain( + names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0])) + ) + + for name in names: + if name in self.url_default_functions: + for func in self.url_default_functions[name]: + func(endpoint, values) + + def handle_url_build_error( + self, error: BuildError, endpoint: str, values: dict[str, t.Any] + ) -> str: + """Called by :meth:`.url_for` if a + :exc:`~werkzeug.routing.BuildError` was raised. If this returns + a value, it will be returned by ``url_for``, otherwise the error + will be re-raised. + + Each function in :attr:`url_build_error_handlers` is called with + ``error``, ``endpoint`` and ``values``. If a function returns + ``None`` or raises a ``BuildError``, it is skipped. Otherwise, + its return value is returned by ``url_for``. + + :param error: The active ``BuildError`` being handled. + :param endpoint: The endpoint being built. + :param values: The keyword arguments passed to ``url_for``. + """ + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + except BuildError as e: + # make error available outside except block + error = e + else: + if rv is not None: + return rv + + # Re-raise if called with an active exception, otherwise raise + # the passed in exception. + if error is sys.exc_info()[1]: + raise + + raise error diff --git a/.venv/lib/python3.11/site-packages/flask/sansio/blueprints.py b/.venv/lib/python3.11/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..4f912cc --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,632 @@ +from __future__ import annotations + +import os +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from .. import typing as ft +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from .app import App + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], None] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any]) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) + + +class BlueprintSetupState: + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__( + self, + blueprint: Blueprint, + app: App, + options: t.Any, + first_registration: bool, + ) -> None: + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get("subdomain") + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get("url_prefix") + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + self.name = self.options.get("name", blueprint.name) + self.name_prefix = self.options.get("name_prefix", "") + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get("url_defaults", ())) + + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + **options: t.Any, + ) -> None: + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/"))) + else: + rule = self.url_prefix + options.setdefault("subdomain", self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + defaults = self.url_defaults + if "defaults" in options: + defaults = dict(defaults, **options.pop("defaults")) + + self.app.add_url_rule( + rule, + f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."), + view_func, + defaults=defaults, + **options, + ) + + +class Blueprint(Scaffold): + """Represents a blueprint, a collection of routes and other + app-related functions that can be registered on a real application + later. + + A blueprint is an object that allows defining application functions + without requiring an application object ahead of time. It uses the + same decorators as :class:`~flask.Flask`, but defers the need for an + application by recording them for later registration. + + Decorating a function with a blueprint creates a deferred function + that is called with :class:`~flask.blueprints.BlueprintSetupState` + when the blueprint is registered on an application. + + See :doc:`/blueprints` for more information. + + :param name: The name of the blueprint. Will be prepended to each + endpoint name. + :param import_name: The name of the blueprint package, usually + ``__name__``. This helps locate the ``root_path`` for the + blueprint. + :param static_folder: A folder with static files that should be + served by the blueprint's static route. The path is relative to + the blueprint's root path. Blueprint static files are disabled + by default. + :param static_url_path: The url to serve static files from. + Defaults to ``static_folder``. If the blueprint does not have + a ``url_prefix``, the app's static route will take precedence, + and the blueprint's static files won't be accessible. + :param template_folder: A folder with templates that should be added + to the app's template search path. The path is relative to the + blueprint's root path. Blueprint templates are disabled by + default. Blueprint templates have a lower precedence than those + in the app's templates folder. + :param url_prefix: A path to prepend to all of the blueprint's URLs, + to make them distinct from the rest of the app's routes. + :param subdomain: A subdomain that blueprint routes will match on by + default. + :param url_defaults: A dict of default values that blueprint routes + will receive by default. + :param root_path: By default, the blueprint will automatically set + this based on ``import_name``. In certain situations this + automatic detection can fail, so the path can be specified + manually instead. + + .. versionchanged:: 1.1.0 + Blueprints have a ``cli`` group to register nested CLI commands. + The ``cli_group`` parameter controls the name of the group under + the ``flask`` command. + + .. versionadded:: 0.7 + """ + + _got_registered_once = False + + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore[assignment] + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if not name: + raise ValueError("'name' may not be empty.") + + if "." in name: + raise ValueError("'name' may not contain a dot '.' character.") + + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.deferred_functions: list[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: list[tuple[Blueprint, dict[str, t.Any]]] = [] + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_registered_once: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called on the blueprint" + f" '{self.name}'. It has already been registered at least once, any" + " changes will not be applied consistently.\n" + "Make sure all imports, decorators, functions, etc. needed to set up" + " the blueprint are done before registering it." + ) + + @setupmethod + def record(self, func: DeferredSetupFunction) -> None: + """Registers a function that is called when the blueprint is + registered on the application. This function is called with the + state as argument as returned by the :meth:`make_setup_state` + method. + """ + self.deferred_functions.append(func) + + @setupmethod + def record_once(self, func: DeferredSetupFunction) -> None: + """Works like :meth:`record` but wraps the function in another + function that will ensure the function is only called once. If the + blueprint is registered a second time on the application, the + function passed is not called. + """ + + def wrapper(state: BlueprintSetupState) -> None: + if state.first_registration: + func(state) + + self.record(update_wrapper(wrapper, func)) + + def make_setup_state( + self, app: App, options: dict[str, t.Any], first_registration: bool = False + ) -> BlueprintSetupState: + """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` + object that is later passed to the register callback functions. + Subclasses can override this to return a subclass of the setup state. + """ + return BlueprintSetupState(self, app, options, first_registration) + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on this blueprint. Keyword + arguments passed to this method will override the defaults set + on the blueprint. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 2.0 + """ + if blueprint is self: + raise ValueError("Cannot register a blueprint on itself") + self._blueprints.append((blueprint, options)) + + def register(self, app: App, options: dict[str, t.Any]) -> None: + """Called by :meth:`Flask.register_blueprint` to register all + views and callbacks registered on the blueprint with the + application. Creates a :class:`.BlueprintSetupState` and calls + each :meth:`record` callback with it. + + :param app: The application this blueprint is being registered + with. + :param options: Keyword arguments forwarded from + :meth:`~Flask.register_blueprint`. + + .. versionchanged:: 2.3 + Nested blueprints now correctly apply subdomains. + + .. versionchanged:: 2.1 + Registering the same blueprint with the same name multiple + times is an error. + + .. versionchanged:: 2.0.1 + Nested blueprints are registered with their dotted name. + This allows different blueprints with the same name to be + nested at different locations. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + """ + name_prefix = options.get("name_prefix", "") + self_name = options.get("name", self.name) + name = f"{name_prefix}.{self_name}".lstrip(".") + + if name in app.blueprints: + bp_desc = "this" if app.blueprints[name] is self else "a different" + existing_at = f" '{name}'" if self_name != name else "" + + raise ValueError( + f"The name '{self_name}' is already registered for" + f" {bp_desc} blueprint{existing_at}. Use 'name=' to" + f" provide a unique name." + ) + + first_bp_registration = not any(bp is self for bp in app.blueprints.values()) + first_name_registration = name not in app.blueprints + + app.blueprints[name] = self + self._got_registered_once = True + state = self.make_setup_state(app, options, first_bp_registration) + + if self.has_static_folder: + state.add_url_rule( + f"{self.static_url_path}/", + view_func=self.send_static_file, # type: ignore[attr-defined] + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + self._merge_blueprint_funcs(app, name) + + for deferred in self.deferred_functions: + deferred(state) + + cli_resolved_group = options.get("cli_group", self.cli_group) + + if self.cli.commands: + if cli_resolved_group is None: + app.cli.commands.update(self.cli.commands) + elif cli_resolved_group is _sentinel: + self.cli.name = name + app.cli.add_command(self.cli) + else: + self.cli.name = cli_resolved_group + app.cli.add_command(self.cli) + + for blueprint, bp_options in self._blueprints: + bp_options = bp_options.copy() + bp_url_prefix = bp_options.get("url_prefix") + bp_subdomain = bp_options.get("subdomain") + + if bp_subdomain is None: + bp_subdomain = blueprint.subdomain + + if state.subdomain is not None and bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + "." + state.subdomain + elif bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + elif state.subdomain is not None: + bp_options["subdomain"] = state.subdomain + + if bp_url_prefix is None: + bp_url_prefix = blueprint.url_prefix + + if state.url_prefix is not None and bp_url_prefix is not None: + bp_options["url_prefix"] = ( + state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") + ) + elif bp_url_prefix is not None: + bp_options["url_prefix"] = bp_url_prefix + elif state.url_prefix is not None: + bp_options["url_prefix"] = state.url_prefix + + bp_options["name_prefix"] = name + blueprint.register(app, bp_options) + + def _merge_blueprint_funcs(self, app: App, name: str) -> None: + def extend( + bp_dict: dict[ft.AppOrBlueprintKey, list[t.Any]], + parent_dict: dict[ft.AppOrBlueprintKey, list[t.Any]], + ) -> None: + for key, values in bp_dict.items(): + key = name if key is None else f"{name}.{key}" + parent_dict[key].extend(values) + + for key, value in self.error_handler_spec.items(): + key = name if key is None else f"{name}.{key}" + value = defaultdict( + dict, + { + code: {exc_class: func for exc_class, func in code_values.items()} + for code, code_values in value.items() + }, + ) + app.error_handler_spec[key] = value + + for endpoint, func in self.view_functions.items(): + app.view_functions[endpoint] = func + + extend(self.before_request_funcs, app.before_request_funcs) + extend(self.after_request_funcs, app.after_request_funcs) + extend( + self.teardown_request_funcs, + app.teardown_request_funcs, + ) + extend(self.url_default_functions, app.url_default_functions) + extend(self.url_value_preprocessors, app.url_value_preprocessors) + extend(self.template_context_processors, app.template_context_processors) + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for + full documentation. + + The URL rule is prefixed with the blueprint's URL prefix. The endpoint name, + used with :func:`url_for`, is prefixed with the blueprint's name. + """ + if endpoint and "." in endpoint: + raise ValueError("'endpoint' may not contain a dot '.' character.") + + if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__: + raise ValueError("'view_func' name may not contain a dot '.' character.") + + self.record( + lambda s: s.add_url_rule( + rule, + endpoint, + view_func, + provide_automatic_options=provide_automatic_options, + **options, + ) + ) + + @setupmethod + def app_template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """Register a template filter, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_app_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a template filter, available in any template rendered by the + application. Works like the :meth:`app_template_filter` decorator. Equivalent to + :meth:`.Flask.add_template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.filters[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """Register a template test, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_app_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a template test, available in any template rendered by the + application. Works like the :meth:`app_template_test` decorator. Equivalent to + :meth:`.Flask.add_template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.tests[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """Register a template global, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_app_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a template global, available in any template rendered by the + application. Works like the :meth:`app_template_global` decorator. Equivalent to + :meth:`.Flask.add_template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.globals[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def before_app_request(self, f: T_before_request) -> T_before_request: + """Like :meth:`before_request`, but before every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.before_request`. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def after_app_request(self, f: T_after_request) -> T_after_request: + """Like :meth:`after_request`, but after every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.after_request`. + """ + self.record_once( + lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def teardown_app_request(self, f: T_teardown) -> T_teardown: + """Like :meth:`teardown_request`, but after every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.teardown_request`. + """ + self.record_once( + lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_context_processor( + self, f: T_template_context_processor + ) -> T_template_context_processor: + """Like :meth:`context_processor`, but for templates rendered by every view, not + only by the blueprint. Equivalent to :meth:`.Flask.context_processor`. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_errorhandler( + self, code: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Like :meth:`errorhandler`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.errorhandler`. + """ + + def decorator(f: T_error_handler) -> T_error_handler: + def from_blueprint(state: BlueprintSetupState) -> None: + state.app.errorhandler(code)(f) + + self.record_once(from_blueprint) + return f + + return decorator + + @setupmethod + def app_url_value_preprocessor( + self, f: T_url_value_preprocessor + ) -> T_url_value_preprocessor: + """Like :meth:`url_value_preprocessor`, but for every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.url_value_preprocessor`. + """ + self.record_once( + lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Like :meth:`url_defaults`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.url_defaults`. + """ + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/.venv/lib/python3.11/site-packages/flask/sansio/scaffold.py b/.venv/lib/python3.11/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..3a839f5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,792 @@ +from __future__ import annotations + +import importlib.util +import os +import pathlib +import sys +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from jinja2 import BaseLoader +from jinja2 import FileSystemLoader +from werkzeug.exceptions import default_exceptions +from werkzeug.exceptions import HTTPException +from werkzeug.utils import cached_property + +from .. import typing as ft +from ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +if t.TYPE_CHECKING: # pragma: no cover + from click import Group + +# a singleton sentinel value for parameter defaults +_sentinel = object() + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any]) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) +T_route = t.TypeVar("T_route", bound=ft.RouteCallable) + + +def setupmethod(f: F) -> F: + f_name = f.__name__ + + def wrapper_func(self: Scaffold, *args: t.Any, **kwargs: t.Any) -> t.Any: + self._check_setup_finished(f_name) + return f(self, *args, **kwargs) + + return t.cast(F, update_wrapper(wrapper_func, f)) + + +class Scaffold: + """Common behavior shared between :class:`~flask.Flask` and + :class:`~flask.blueprints.Blueprint`. + + :param import_name: The import name of the module where this object + is defined. Usually :attr:`__name__` should be used. + :param static_folder: Path to a folder of static files to serve. + If this is set, a static route will be added. + :param static_url_path: URL prefix for the static route. + :param template_folder: Path to a folder containing template files. + for rendering. If this is set, a Jinja loader will be added. + :param root_path: The path that static, template, and resource files + are relative to. Typically not set, it is discovered based on + the ``import_name``. + + .. versionadded:: 2.0 + """ + + cli: Group + name: str + _static_folder: str | None = None + _static_url_path: str | None = None + + def __init__( + self, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + root_path: str | None = None, + ): + #: The name of the package or module that this object belongs + #: to. Do not change this once it is set by the constructor. + self.import_name = import_name + + self.static_folder = static_folder # type: ignore + self.static_url_path = static_url_path + + #: The path to the templates folder, relative to + #: :attr:`root_path`, to add to the template loader. ``None`` if + #: templates should not be added. + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + #: Absolute path to the package on the filesystem. Used to look + #: up resources contained in the package. + self.root_path = root_path + + #: A dictionary mapping endpoint names to view functions. + #: + #: To register a view function, use the :meth:`route` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.view_functions: dict[str, ft.RouteCallable] = {} + + #: A data structure of registered error handlers, in the format + #: ``{scope: {code: {class: handler}}}``. The ``scope`` key is + #: the name of a blueprint the handlers are active for, or + #: ``None`` for all requests. The ``code`` key is the HTTP + #: status code for ``HTTPException``, or ``None`` for + #: other exceptions. The innermost dictionary maps exception + #: classes to handler functions. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.error_handler_spec: dict[ + ft.AppOrBlueprintKey, + dict[int | None, dict[type[Exception], ft.ErrorHandlerCallable]], + ] = defaultdict(lambda: defaultdict(dict)) + + #: A data structure of functions to call at the beginning of + #: each request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`before_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.before_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.BeforeRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`after_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.after_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.AfterRequestCallable[t.Any]] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request even if an exception is raised, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`teardown_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.teardown_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.TeardownCallable] + ] = defaultdict(list) + + #: A data structure of functions to call to pass extra context + #: values when rendering templates, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`context_processor` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.template_context_processors: dict[ + ft.AppOrBlueprintKey, list[ft.TemplateContextProcessorCallable] + ] = defaultdict(list, {None: [_default_template_ctx_processor]}) + + #: A data structure of functions to call to modify the keyword + #: arguments passed to the view function, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the + #: :meth:`url_value_preprocessor` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_value_preprocessors: dict[ + ft.AppOrBlueprintKey, + list[ft.URLValuePreprocessorCallable], + ] = defaultdict(list) + + #: A data structure of functions to call to modify the keyword + #: arguments when generating URLs, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`url_defaults` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_default_functions: dict[ + ft.AppOrBlueprintKey, list[ft.URLDefaultCallable] + ] = defaultdict(list) + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.name!r}>" + + def _check_setup_finished(self, f_name: str) -> None: + raise NotImplementedError + + @property + def static_folder(self) -> str | None: + """The absolute path to the configured static folder. ``None`` + if no static folder is set. + """ + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + else: + return None + + @static_folder.setter + def static_folder(self, value: str | os.PathLike[str] | None) -> None: + if value is not None: + value = os.fspath(value).rstrip(r"\/") + + self._static_folder = value + + @property + def has_static_folder(self) -> bool: + """``True`` if :attr:`static_folder` is set. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @property + def static_url_path(self) -> str | None: + """The URL prefix that the static route will be accessible from. + + If it was not configured during init, it is derived from + :attr:`static_folder`. + """ + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + basename = os.path.basename(self.static_folder) + return f"/{basename}".rstrip("/") + + return None + + @static_url_path.setter + def static_url_path(self, value: str | None) -> None: + if value is not None: + value = value.rstrip("/") + + self._static_url_path = value + + @cached_property + def jinja_loader(self) -> BaseLoader | None: + """The Jinja loader for this object's templates. By default this + is a class :class:`jinja2.loaders.FileSystemLoader` to + :attr:`template_folder` if it is set. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, self.template_folder)) + else: + return None + + def _method_route( + self, + method: str, + rule: str, + options: dict[str, t.Any], + ) -> t.Callable[[T_route], T_route]: + if "methods" in options: + raise TypeError("Use the 'route' decorator to use the 'methods' argument.") + + return self.route(rule, methods=[method], **options) + + @setupmethod + def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["GET"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("GET", rule, options) + + @setupmethod + def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["POST"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("POST", rule, options) + + @setupmethod + def put(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PUT"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PUT", rule, options) + + @setupmethod + def delete(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["DELETE"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("DELETE", rule, options) + + @setupmethod + def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PATCH"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PATCH", rule, options) + + @setupmethod + def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Decorate a view function to register it with the given URL + rule and options. Calls :meth:`add_url_rule`, which has more + details about the implementation. + + .. code-block:: python + + @app.route("/") + def index(): + return "Hello, World!" + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` and + ``OPTIONS`` are added automatically. + + :param rule: The URL rule string. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + + def decorator(f: T_route) -> T_route: + endpoint = options.pop("endpoint", None) + self.add_url_rule(rule, endpoint, f, **options) + return f + + return decorator + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a rule for routing incoming requests and building + URLs. The :meth:`route` decorator is a shortcut to call this + with the ``view_func`` argument. These are equivalent: + + .. code-block:: python + + @app.route("/") + def index(): + ... + + .. code-block:: python + + def index(): + ... + + app.add_url_rule("/", view_func=index) + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. An error + will be raised if a function has already been registered for the + endpoint. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` is + always added automatically, and ``OPTIONS`` is added + automatically by default. + + ``view_func`` does not necessarily need to be passed, but if the + rule should participate in routing an endpoint name must be + associated with a view function at some point with the + :meth:`endpoint` decorator. + + .. code-block:: python + + app.add_url_rule("/", endpoint="index") + + @app.endpoint("index") + def index(): + ... + + If ``view_func`` has a ``required_methods`` attribute, those + methods are added to the passed and automatic methods. If it + has a ``provide_automatic_methods`` attribute, it is used as the + default if the parameter is not passed. + + :param rule: The URL rule string. + :param endpoint: The endpoint name to associate with the rule + and view function. Used when routing and building URLs. + Defaults to ``view_func.__name__``. + :param view_func: The view function to associate with the + endpoint name. + :param provide_automatic_options: Add the ``OPTIONS`` method and + respond to ``OPTIONS`` requests automatically. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + raise NotImplementedError + + @setupmethod + def endpoint(self, endpoint: str) -> t.Callable[[F], F]: + """Decorate a view function to register it for the given + endpoint. Used if a rule is added without a ``view_func`` with + :meth:`add_url_rule`. + + .. code-block:: python + + app.add_url_rule("/ex", endpoint="example") + + @app.endpoint("example") + def example(): + ... + + :param endpoint: The endpoint name to associate with the view + function. + """ + + def decorator(f: F) -> F: + self.view_functions[endpoint] = f + return f + + return decorator + + @setupmethod + def before_request(self, f: T_before_request) -> T_before_request: + """Register a function to run before each request. + + For example, this can be used to open a database connection, or + to load the logged in user from the session. + + .. code-block:: python + + @app.before_request + def load_user(): + if "user_id" in session: + g.user = db.session.get(session["user_id"]) + + The function will be called without any arguments. If it returns + a non-``None`` value, the value is handled as if it was the + return value from the view, and further request handling is + stopped. + + This is available on both app and blueprint objects. When used on an app, this + executes before every request. When used on a blueprint, this executes before + every request that the blueprint handles. To register with a blueprint and + execute before every request, use :meth:`.Blueprint.before_app_request`. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def after_request(self, f: T_after_request) -> T_after_request: + """Register a function to run after each request to this object. + + The function is called with the response object, and must return + a response object. This allows the functions to modify or + replace the response before it is sent. + + If a function raises an exception, any remaining + ``after_request`` functions will not be called. Therefore, this + should not be used for actions that must execute, such as to + close resources. Use :meth:`teardown_request` for that. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.after_app_request`. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f: T_teardown) -> T_teardown: + """Register a function to be called when the request context is + popped. Typically this happens at the end of each request, but + contexts may be pushed manually as well during testing. + + .. code-block:: python + + with app.test_request_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the request context is + made inactive. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.teardown_app_request`. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def context_processor( + self, + f: T_template_context_processor, + ) -> T_template_context_processor: + """Registers a template context processor function. These functions run before + rendering a template. The keys of the returned dict are added as variables + available in the template. + + This is available on both app and blueprint objects. When used on an app, this + is called for every rendered template. When used on a blueprint, this is called + for templates rendered from the blueprint's views. To register with a blueprint + and affect every template, use :meth:`.Blueprint.app_context_processor`. + """ + self.template_context_processors[None].append(f) + return f + + @setupmethod + def url_value_preprocessor( + self, + f: T_url_value_preprocessor, + ) -> T_url_value_preprocessor: + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_value_preprocessor`. + """ + self.url_value_preprocessors[None].append(f) + return f + + @setupmethod + def url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_defaults`. + """ + self.url_default_functions[None].append(f) + return f + + @setupmethod + def errorhandler( + self, code_or_exception: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + This is available on both app and blueprint objects. When used on an app, this + can handle errors from every request. When used on a blueprint, this can handle + errors from requests that the blueprint handles. To register with a blueprint + and affect every request, use :meth:`.Blueprint.app_errorhandler`. + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.register_error_handler(code_or_exception, f) + return f + + return decorator + + @setupmethod + def register_error_handler( + self, + code_or_exception: type[Exception] | int, + f: ft.ErrorHandlerCallable, + ) -> None: + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + exc_class, code = self._get_exc_class_and_code(code_or_exception) + self.error_handler_spec[None][code][exc_class] = f + + @staticmethod + def _get_exc_class_and_code( + exc_class_or_code: type[Exception] | int, + ) -> tuple[type[Exception], int | None]: + """Get the exception class being handled. For HTTP status codes + or ``HTTPException`` subclasses, return both the exception and + status code. + + :param exc_class_or_code: Any exception class, or an HTTP status + code as an integer. + """ + exc_class: type[Exception] + + if isinstance(exc_class_or_code, int): + try: + exc_class = default_exceptions[exc_class_or_code] + except KeyError: + raise ValueError( + f"'{exc_class_or_code}' is not a recognized HTTP" + " error code. Use a subclass of HTTPException with" + " that code instead." + ) from None + else: + exc_class = exc_class_or_code + + if isinstance(exc_class, Exception): + raise TypeError( + f"{exc_class!r} is an instance, not a class. Handlers" + " can only be registered for Exception classes or HTTP" + " error codes." + ) + + if not issubclass(exc_class, Exception): + raise ValueError( + f"'{exc_class.__name__}' is not a subclass of Exception." + " Handlers can only be registered for Exception classes" + " or HTTP error codes." + ) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + +def _endpoint_from_view_func(view_func: ft.RouteCallable) -> str: + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, "expected view func if endpoint is not provided." + return view_func.__name__ + + +def _find_package_path(import_name: str) -> str: + """Find the path that contains the package or module.""" + root_mod_name, _, _ = import_name.partition(".") + + try: + root_spec = importlib.util.find_spec(root_mod_name) + + if root_spec is None: + raise ValueError("not found") + except (ImportError, ValueError): + # ImportError: the machinery told us it does not exist + # ValueError: + # - the module name was invalid + # - the module name is __main__ + # - we raised `ValueError` due to `root_spec` being `None` + return os.getcwd() + + if root_spec.submodule_search_locations: + if root_spec.origin is None or root_spec.origin == "namespace": + # namespace package + package_spec = importlib.util.find_spec(import_name) + + if package_spec is not None and package_spec.submodule_search_locations: + # Pick the path in the namespace that contains the submodule. + package_path = pathlib.Path( + os.path.commonpath(package_spec.submodule_search_locations) + ) + search_location = next( + location + for location in root_spec.submodule_search_locations + if package_path.is_relative_to(location) + ) + else: + # Pick the first path. + search_location = root_spec.submodule_search_locations[0] + + return os.path.dirname(search_location) + else: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) # type: ignore[type-var, return-value] + + +def find_package(import_name: str) -> tuple[str | None, str]: + """Find the prefix that a package is installed under, and the path + that it would be imported from. + + The prefix is the directory containing the standard directory + hierarchy (lib, bin, etc.). If the package is not installed to the + system (:attr:`sys.prefix`) or a virtualenv (``site-packages``), + ``None`` is returned. + + The path is the entry in :attr:`sys.path` that contains the package + for import. If the package is not installed, it's assumed that the + package was imported from the current working directory. + """ + package_path = _find_package_path(import_name) + py_prefix = os.path.abspath(sys.prefix) + + # installed to the system + if pathlib.PurePath(package_path).is_relative_to(py_prefix): + return py_prefix, package_path + + site_parent, site_folder = os.path.split(package_path) + + # installed to a virtualenv + if site_folder.lower() == "site-packages": + parent, folder = os.path.split(site_parent) + + # Windows (prefix/lib/site-packages) + if folder.lower() == "lib": + return parent, package_path + + # Unix (prefix/lib/pythonX.Y/site-packages) + if os.path.basename(parent).lower() == "lib": + return os.path.dirname(parent), package_path + + # something else (prefix/site-packages) + return site_parent, package_path + + # not installed + return None, package_path diff --git a/.venv/lib/python3.11/site-packages/flask/sessions.py b/.venv/lib/python3.11/site-packages/flask/sessions.py new file mode 100644 index 0000000..375de06 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/sessions.py @@ -0,0 +1,398 @@ +from __future__ import annotations + +import collections.abc as c +import hashlib +import typing as t +from collections.abc import MutableMapping +from datetime import datetime +from datetime import timezone + +from itsdangerous import BadSignature +from itsdangerous import URLSafeTimedSerializer +from werkzeug.datastructures import CallbackDict + +from .json.tag import TaggedJSONSerializer + +if t.TYPE_CHECKING: # pragma: no cover + import typing_extensions as te + + from .app import Flask + from .wrappers import Request + from .wrappers import Response + + +class SessionMixin(MutableMapping[str, t.Any]): + """Expands a basic dictionary with session attributes.""" + + @property + def permanent(self) -> bool: + """This reflects the ``'_permanent'`` key in the dict.""" + return self.get("_permanent", False) + + @permanent.setter + def permanent(self, value: bool) -> None: + self["_permanent"] = bool(value) + + #: Some implementations can detect whether a session is newly + #: created, but that is not guaranteed. Use with caution. The mixin + # default is hard-coded ``False``. + new = False + + #: Some implementations can detect changes to the session and set + #: this when that happens. The mixin default is hard coded to + #: ``True``. + modified = True + + #: Some implementations can detect when session data is read or + #: written and set this when that happens. The mixin default is hard + #: coded to ``True``. + accessed = True + + +class SecureCookieSession(CallbackDict[str, t.Any], SessionMixin): + """Base class for sessions based on signed cookies. + + This session backend will set the :attr:`modified` and + :attr:`accessed` attributes. It cannot reliably track whether a + session is new (vs. empty), so :attr:`new` remains hard coded to + ``False``. + """ + + #: When data is changed, this is set to ``True``. Only the session + #: dictionary itself is tracked; if the session contains mutable + #: data (for example a nested dict) then this must be set to + #: ``True`` manually when modifying that data. The session cookie + #: will only be written to the response if this is ``True``. + modified = False + + #: When data is read or written, this is set to ``True``. Used by + # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie`` + #: header, which allows caching proxies to cache different pages for + #: different users. + accessed = False + + def __init__( + self, + initial: c.Mapping[str, t.Any] | c.Iterable[tuple[str, t.Any]] | None = None, + ) -> None: + def on_update(self: te.Self) -> None: + self.modified = True + self.accessed = True + + super().__init__(initial, on_update) + + def __getitem__(self, key: str) -> t.Any: + self.accessed = True + return super().__getitem__(key) + + def get(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().get(key, default) + + def setdefault(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().setdefault(key, default) + + +class NullSession(SecureCookieSession): + """Class used to generate nicer error messages if sessions are not + available. Will still allow read-only access to the empty session + but fail on setting. + """ + + def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + raise RuntimeError( + "The session is unavailable because no secret " + "key was set. Set the secret_key on the " + "application to something unique and secret." + ) + + __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # type: ignore # noqa: B950 + del _fail + + +class SessionInterface: + """The basic interface you have to implement in order to replace the + default session interface which uses werkzeug's securecookie + implementation. The only methods you have to implement are + :meth:`open_session` and :meth:`save_session`, the others have + useful defaults which you don't need to change. + + The session object returned by the :meth:`open_session` method has to + provide a dictionary like interface plus the properties and methods + from the :class:`SessionMixin`. We recommend just subclassing a dict + and adding that mixin:: + + class Session(dict, SessionMixin): + pass + + If :meth:`open_session` returns ``None`` Flask will call into + :meth:`make_null_session` to create a session that acts as replacement + if the session support cannot work because some requirement is not + fulfilled. The default :class:`NullSession` class that is created + will complain that the secret key was not set. + + To replace the session interface on an application all you have to do + is to assign :attr:`flask.Flask.session_interface`:: + + app = Flask(__name__) + app.session_interface = MySessionInterface() + + Multiple requests with the same session may be sent and handled + concurrently. When implementing a new session interface, consider + whether reads or writes to the backing store must be synchronized. + There is no guarantee on the order in which the session for each + request is opened or saved, it will occur in the order that requests + begin and end processing. + + .. versionadded:: 0.8 + """ + + #: :meth:`make_null_session` will look here for the class that should + #: be created when a null session is requested. Likewise the + #: :meth:`is_null_session` method will perform a typecheck against + #: this type. + null_session_class = NullSession + + #: A flag that indicates if the session interface is pickle based. + #: This can be used by Flask extensions to make a decision in regards + #: to how to deal with the session object. + #: + #: .. versionadded:: 0.10 + pickle_based = False + + def make_null_session(self, app: Flask) -> NullSession: + """Creates a null session which acts as a replacement object if the + real session support could not be loaded due to a configuration + error. This mainly aids the user experience because the job of the + null session is to still support lookup without complaining but + modifications are answered with a helpful error message of what + failed. + + This creates an instance of :attr:`null_session_class` by default. + """ + return self.null_session_class() + + def is_null_session(self, obj: object) -> bool: + """Checks if a given object is a null session. Null sessions are + not asked to be saved. + + This checks if the object is an instance of :attr:`null_session_class` + by default. + """ + return isinstance(obj, self.null_session_class) + + def get_cookie_name(self, app: Flask) -> str: + """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``.""" + return app.config["SESSION_COOKIE_NAME"] # type: ignore[no-any-return] + + def get_cookie_domain(self, app: Flask) -> str | None: + """The value of the ``Domain`` parameter on the session cookie. If not set, + browsers will only send the cookie to the exact domain it was set from. + Otherwise, they will send it to any subdomain of the given value as well. + + Uses the :data:`SESSION_COOKIE_DOMAIN` config. + + .. versionchanged:: 2.3 + Not set by default, does not fall back to ``SERVER_NAME``. + """ + return app.config["SESSION_COOKIE_DOMAIN"] # type: ignore[no-any-return] + + def get_cookie_path(self, app: Flask) -> str: + """Returns the path for which the cookie should be valid. The + default implementation uses the value from the ``SESSION_COOKIE_PATH`` + config var if it's set, and falls back to ``APPLICATION_ROOT`` or + uses ``/`` if it's ``None``. + """ + return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"] # type: ignore[no-any-return] + + def get_cookie_httponly(self, app: Flask) -> bool: + """Returns True if the session cookie should be httponly. This + currently just returns the value of the ``SESSION_COOKIE_HTTPONLY`` + config var. + """ + return app.config["SESSION_COOKIE_HTTPONLY"] # type: ignore[no-any-return] + + def get_cookie_secure(self, app: Flask) -> bool: + """Returns True if the cookie should be secure. This currently + just returns the value of the ``SESSION_COOKIE_SECURE`` setting. + """ + return app.config["SESSION_COOKIE_SECURE"] # type: ignore[no-any-return] + + def get_cookie_samesite(self, app: Flask) -> str | None: + """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the + ``SameSite`` attribute. This currently just returns the value of + the :data:`SESSION_COOKIE_SAMESITE` setting. + """ + return app.config["SESSION_COOKIE_SAMESITE"] # type: ignore[no-any-return] + + def get_cookie_partitioned(self, app: Flask) -> bool: + """Returns True if the cookie should be partitioned. By default, uses + the value of :data:`SESSION_COOKIE_PARTITIONED`. + + .. versionadded:: 3.1 + """ + return app.config["SESSION_COOKIE_PARTITIONED"] # type: ignore[no-any-return] + + def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None: + """A helper method that returns an expiration date for the session + or ``None`` if the session is linked to the browser session. The + default implementation returns now + the permanent session + lifetime configured on the application. + """ + if session.permanent: + return datetime.now(timezone.utc) + app.permanent_session_lifetime + return None + + def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool: + """Used by session backends to determine if a ``Set-Cookie`` header + should be set for this session cookie for this response. If the session + has been modified, the cookie is set. If the session is permanent and + the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is + always set. + + This check is usually skipped if the session was deleted. + + .. versionadded:: 0.11 + """ + + return session.modified or ( + session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"] + ) + + def open_session(self, app: Flask, request: Request) -> SessionMixin | None: + """This is called at the beginning of each request, after + pushing the request context, before matching the URL. + + This must return an object which implements a dictionary-like + interface as well as the :class:`SessionMixin` interface. + + This will return ``None`` to indicate that loading failed in + some way that is not immediately an error. The request + context will fall back to using :meth:`make_null_session` + in this case. + """ + raise NotImplementedError() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + """This is called at the end of each request, after generating + a response, before removing the request context. It is skipped + if :meth:`is_null_session` returns ``True``. + """ + raise NotImplementedError() + + +session_json_serializer = TaggedJSONSerializer() + + +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + +class SecureCookieSessionInterface(SessionInterface): + """The default session interface that stores sessions in signed cookies + through the :mod:`itsdangerous` module. + """ + + #: the salt that should be applied on top of the secret key for the + #: signing of cookie based sessions. + salt = "cookie-session" + #: the hash function to use for the signature. The default is sha1 + digest_method = staticmethod(_lazy_sha1) + #: the name of the itsdangerous supported key derivation. The default + #: is hmac. + key_derivation = "hmac" + #: A python serializer for the payload. The default is a compact + #: JSON derived serializer with support for some extra Python types + #: such as datetime objects or tuples. + serializer = session_json_serializer + session_class = SecureCookieSession + + def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: + if not app.secret_key: + return None + + keys: list[str | bytes] = [app.secret_key] + + if fallbacks := app.config["SECRET_KEY_FALLBACKS"]: + keys.extend(fallbacks) + + return URLSafeTimedSerializer( + keys, # type: ignore[arg-type] + salt=self.salt, + serializer=self.serializer, + signer_kwargs={ + "key_derivation": self.key_derivation, + "digest_method": self.digest_method, + }, + ) + + def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: + s = self.get_signing_serializer(app) + if s is None: + return None + val = request.cookies.get(self.get_cookie_name(app)) + if not val: + return self.session_class() + max_age = int(app.permanent_session_lifetime.total_seconds()) + try: + data = s.loads(val, max_age=max_age) + return self.session_class(data) + except BadSignature: + return self.session_class() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + name = self.get_cookie_name(app) + domain = self.get_cookie_domain(app) + path = self.get_cookie_path(app) + secure = self.get_cookie_secure(app) + partitioned = self.get_cookie_partitioned(app) + samesite = self.get_cookie_samesite(app) + httponly = self.get_cookie_httponly(app) + + # Add a "Vary: Cookie" header if the session was accessed at all. + if session.accessed: + response.vary.add("Cookie") + + # If the session is modified to be empty, remove the cookie. + # If the session is empty, return without setting the cookie. + if not session: + if session.modified: + response.delete_cookie( + name, + domain=domain, + path=path, + secure=secure, + partitioned=partitioned, + samesite=samesite, + httponly=httponly, + ) + response.vary.add("Cookie") + + return + + if not self.should_set_cookie(app, session): + return + + expires = self.get_expiration_time(app, session) + val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore[union-attr] + response.set_cookie( + name, + val, + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + partitioned=partitioned, + samesite=samesite, + ) + response.vary.add("Cookie") diff --git a/.venv/lib/python3.11/site-packages/flask/signals.py b/.venv/lib/python3.11/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/signals.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from blinker import Namespace + +# This namespace is only for signals provided by Flask itself. +_signals = Namespace() + +template_rendered = _signals.signal("template-rendered") +before_render_template = _signals.signal("before-render-template") +request_started = _signals.signal("request-started") +request_finished = _signals.signal("request-finished") +request_tearing_down = _signals.signal("request-tearing-down") +got_request_exception = _signals.signal("got-request-exception") +appcontext_tearing_down = _signals.signal("appcontext-tearing-down") +appcontext_pushed = _signals.signal("appcontext-pushed") +appcontext_popped = _signals.signal("appcontext-popped") +message_flashed = _signals.signal("message-flashed") diff --git a/.venv/lib/python3.11/site-packages/flask/templating.py b/.venv/lib/python3.11/site-packages/flask/templating.py new file mode 100644 index 0000000..618a3b3 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/templating.py @@ -0,0 +1,219 @@ +from __future__ import annotations + +import typing as t + +from jinja2 import BaseLoader +from jinja2 import Environment as BaseEnvironment +from jinja2 import Template +from jinja2 import TemplateNotFound + +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .helpers import stream_with_context +from .signals import before_render_template +from .signals import template_rendered + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sansio.app import App + from .sansio.scaffold import Scaffold + + +def _default_template_ctx_processor() -> dict[str, t.Any]: + """Default template context processor. Injects `request`, + `session` and `g`. + """ + appctx = _cv_app.get(None) + reqctx = _cv_request.get(None) + rv: dict[str, t.Any] = {} + if appctx is not None: + rv["g"] = appctx.g + if reqctx is not None: + rv["request"] = reqctx.request + rv["session"] = reqctx.session + return rv + + +class Environment(BaseEnvironment): + """Works like a regular Jinja2 environment but has some additional + knowledge of how Flask's blueprint works so that it can prepend the + name of the blueprint to referenced templates if necessary. + """ + + def __init__(self, app: App, **options: t.Any) -> None: + if "loader" not in options: + options["loader"] = app.create_global_jinja_loader() + BaseEnvironment.__init__(self, **options) + self.app = app + + +class DispatchingJinjaLoader(BaseLoader): + """A loader that looks for templates in the application and all + the blueprint folders. + """ + + def __init__(self, app: App) -> None: + self.app = app + + def get_source( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | None]: + if self.app.config["EXPLAIN_TEMPLATE_LOADING"]: + return self._get_source_explained(environment, template) + return self._get_source_fast(environment, template) + + def _get_source_explained( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | None]: + attempts = [] + rv: tuple[str, str | None, t.Callable[[], bool] | None] | None + trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None + + for srcobj, loader in self._iter_loaders(template): + try: + rv = loader.get_source(environment, template) + if trv is None: + trv = rv + except TemplateNotFound: + rv = None + attempts.append((loader, srcobj, rv)) + + from .debughelpers import explain_template_loading_attempts + + explain_template_loading_attempts(self.app, template, attempts) + + if trv is not None: + return trv + raise TemplateNotFound(template) + + def _get_source_fast( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | None]: + for _srcobj, loader in self._iter_loaders(template): + try: + return loader.get_source(environment, template) + except TemplateNotFound: + continue + raise TemplateNotFound(template) + + def _iter_loaders(self, template: str) -> t.Iterator[tuple[Scaffold, BaseLoader]]: + loader = self.app.jinja_loader + if loader is not None: + yield self.app, loader + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + yield blueprint, loader + + def list_templates(self) -> list[str]: + result = set() + loader = self.app.jinja_loader + if loader is not None: + result.update(loader.list_templates()) + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + for template in loader.list_templates(): + result.add(template) + + return list(result) + + +def _render(app: Flask, template: Template, context: dict[str, t.Any]) -> str: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + rv = template.render(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + return rv + + +def render_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> str: + """Render a template by name with the given context. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _render(app, template, context) + + +def render_template_string(source: str, **context: t.Any) -> str: + """Render a template from the given source string with the given + context. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _render(app, template, context) + + +def _stream( + app: Flask, template: Template, context: dict[str, t.Any] +) -> t.Iterator[str]: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + def generate() -> t.Iterator[str]: + yield from template.generate(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + rv = generate() + + # If a request context is active, keep it while generating. + if request: + rv = stream_with_context(rv) + + return rv + + +def stream_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> t.Iterator[str]: + """Render a template by name with the given context as a stream. + This returns an iterator of strings, which can be used as a + streaming response from a view. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _stream(app, template, context) + + +def stream_template_string(source: str, **context: t.Any) -> t.Iterator[str]: + """Render a template from the given source string with the given + context as a stream. This returns an iterator of strings, which can + be used as a streaming response from a view. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _stream(app, template, context) diff --git a/.venv/lib/python3.11/site-packages/flask/testing.py b/.venv/lib/python3.11/site-packages/flask/testing.py new file mode 100644 index 0000000..602b773 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/testing.py @@ -0,0 +1,297 @@ +from __future__ import annotations + +import importlib.metadata +import typing as t +from contextlib import contextmanager +from contextlib import ExitStack +from copy import copy +from types import TracebackType +from urllib.parse import urlsplit + +import werkzeug.test +from click.testing import CliRunner +from werkzeug.test import Client +from werkzeug.wrappers import Request as BaseRequest + +from .cli import ScriptInfo +from .sessions import SessionMixin + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIEnvironment + from werkzeug.test import TestResponse + + from .app import Flask + + +class EnvironBuilder(werkzeug.test.EnvironBuilder): + """An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the + application. + + :param app: The Flask application to configure the environment from. + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + + def __init__( + self, + app: Flask, + path: str = "/", + base_url: str | None = None, + subdomain: str | None = None, + url_scheme: str | None = None, + *args: t.Any, + **kwargs: t.Any, + ) -> None: + assert not (base_url or subdomain or url_scheme) or ( + base_url is not None + ) != bool( + subdomain or url_scheme + ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + + if base_url is None: + http_host = app.config.get("SERVER_NAME") or "localhost" + app_root = app.config["APPLICATION_ROOT"] + + if subdomain: + http_host = f"{subdomain}.{http_host}" + + if url_scheme is None: + url_scheme = app.config["PREFERRED_URL_SCHEME"] + + url = urlsplit(path) + base_url = ( + f"{url.scheme or url_scheme}://{url.netloc or http_host}" + f"/{app_root.lstrip('/')}" + ) + path = url.path + + if url.query: + path = f"{path}?{url.query}" + + self.app = app + super().__init__(path, base_url, *args, **kwargs) + + def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str: # type: ignore + """Serialize ``obj`` to a JSON-formatted string. + + The serialization will be configured according to the config associated + with this EnvironBuilder's ``app``. + """ + return self.app.json.dumps(obj, **kwargs) + + +_werkzeug_version = "" + + +def _get_werkzeug_version() -> str: + global _werkzeug_version + + if not _werkzeug_version: + _werkzeug_version = importlib.metadata.version("werkzeug") + + return _werkzeug_version + + +class FlaskClient(Client): + """Works like a regular Werkzeug test client but has knowledge about + Flask's contexts to defer the cleanup of the request context until + the end of a ``with`` block. For general information about how to + use this class refer to :class:`werkzeug.test.Client`. + + .. versionchanged:: 0.12 + `app.test_client()` includes preset default environment, which can be + set after instantiation of the `app.test_client()` object in + `client.environ_base`. + + Basic usage is outlined in the :doc:`/testing` chapter. + """ + + application: Flask + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + super().__init__(*args, **kwargs) + self.preserve_context = False + self._new_contexts: list[t.ContextManager[t.Any]] = [] + self._context_stack = ExitStack() + self.environ_base = { + "REMOTE_ADDR": "127.0.0.1", + "HTTP_USER_AGENT": f"Werkzeug/{_get_werkzeug_version()}", + } + + @contextmanager + def session_transaction( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Iterator[SessionMixin]: + """When used in combination with a ``with`` statement this opens a + session transaction. This can be used to modify the session that + the test client uses. Once the ``with`` block is left the session is + stored back. + + :: + + with client.session_transaction() as session: + session['value'] = 42 + + Internally this is implemented by going through a temporary test + request context and since session handling could depend on + request variables this function accepts the same arguments as + :meth:`~flask.Flask.test_request_context` which are directly + passed through. + """ + if self._cookies is None: + raise TypeError( + "Cookies are disabled. Create a client with 'use_cookies=True'." + ) + + app = self.application + ctx = app.test_request_context(*args, **kwargs) + self._add_cookies_to_wsgi(ctx.request.environ) + + with ctx: + sess = app.session_interface.open_session(app, ctx.request) + + if sess is None: + raise RuntimeError("Session backend did not open a session.") + + yield sess + resp = app.response_class() + + if app.session_interface.is_null_session(sess): + return + + with ctx: + app.session_interface.save_session(app, sess, resp) + + self._update_cookies_from_response( + ctx.request.host.partition(":")[0], + ctx.request.path, + resp.headers.getlist("Set-Cookie"), + ) + + def _copy_environ(self, other: WSGIEnvironment) -> WSGIEnvironment: + out = {**self.environ_base, **other} + + if self.preserve_context: + out["werkzeug.debug.preserve_context"] = self._new_contexts.append + + return out + + def _request_from_builder_args( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> BaseRequest: + kwargs["environ_base"] = self._copy_environ(kwargs.get("environ_base", {})) + builder = EnvironBuilder(self.application, *args, **kwargs) + + try: + return builder.get_request() + finally: + builder.close() + + def open( + self, + *args: t.Any, + buffered: bool = False, + follow_redirects: bool = False, + **kwargs: t.Any, + ) -> TestResponse: + if args and isinstance( + args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest) + ): + if isinstance(args[0], werkzeug.test.EnvironBuilder): + builder = copy(args[0]) + builder.environ_base = self._copy_environ(builder.environ_base or {}) # type: ignore[arg-type] + request = builder.get_request() + elif isinstance(args[0], dict): + request = EnvironBuilder.from_environ( + args[0], app=self.application, environ_base=self._copy_environ({}) + ).get_request() + else: + # isinstance(args[0], BaseRequest) + request = copy(args[0]) + request.environ = self._copy_environ(request.environ) + else: + # request is None + request = self._request_from_builder_args(args, kwargs) + + # Pop any previously preserved contexts. This prevents contexts + # from being preserved across redirects or multiple requests + # within a single block. + self._context_stack.close() + + response = super().open( + request, + buffered=buffered, + follow_redirects=follow_redirects, + ) + response.json_module = self.application.json # type: ignore[assignment] + + # Re-push contexts that were preserved during the request. + while self._new_contexts: + cm = self._new_contexts.pop() + self._context_stack.enter_context(cm) + + return response + + def __enter__(self) -> FlaskClient: + if self.preserve_context: + raise RuntimeError("Cannot nest client invocations") + self.preserve_context = True + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.preserve_context = False + self._context_stack.close() + + +class FlaskCliRunner(CliRunner): + """A :class:`~click.testing.CliRunner` for testing a Flask app's + CLI commands. Typically created using + :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`. + """ + + def __init__(self, app: Flask, **kwargs: t.Any) -> None: + self.app = app + super().__init__(**kwargs) + + def invoke( # type: ignore + self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any + ) -> t.Any: + """Invokes a CLI command in an isolated environment. See + :meth:`CliRunner.invoke ` for + full method documentation. See :ref:`testing-cli` for examples. + + If the ``obj`` argument is not given, passes an instance of + :class:`~flask.cli.ScriptInfo` that knows how to load the Flask + app being tested. + + :param cli: Command object to invoke. Default is the app's + :attr:`~flask.app.Flask.cli` group. + :param args: List of strings to invoke the command with. + + :return: a :class:`~click.testing.Result` object. + """ + if cli is None: + cli = self.app.cli + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/.venv/lib/python3.11/site-packages/flask/typing.py b/.venv/lib/python3.11/site-packages/flask/typing.py new file mode 100644 index 0000000..e7234e9 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/typing.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +import typing as t + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIApplication # noqa: F401 + from werkzeug.datastructures import Headers # noqa: F401 + from werkzeug.sansio.response import Response # noqa: F401 + +# The possible types that are directly convertible or are a Response object. +ResponseValue = t.Union[ + "Response", + str, + bytes, + list[t.Any], + # Only dict is actually accepted, but Mapping allows for TypedDict. + t.Mapping[str, t.Any], + t.Iterator[str], + t.Iterator[bytes], +] + +# the possible types for an individual HTTP header +# This should be a Union, but mypy doesn't pass unless it's a TypeVar. +HeaderValue = t.Union[str, list[str], tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + tuple[ResponseValue, HeadersValue], + tuple[ResponseValue, int], + tuple[ResponseValue, int, HeadersValue], + "WSGIApplication", +] + +# Allow any subclass of werkzeug.Response, such as the one from Flask, +# as a callback argument. Using werkzeug.Response directly makes a +# callback annotated with flask.Response fail type checking. +ResponseClass = t.TypeVar("ResponseClass", bound="Response") + +AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named +AfterRequestCallable = t.Union[ + t.Callable[[ResponseClass], ResponseClass], + t.Callable[[ResponseClass], t.Awaitable[ResponseClass]], +] +BeforeFirstRequestCallable = t.Union[ + t.Callable[[], None], t.Callable[[], t.Awaitable[None]] +] +BeforeRequestCallable = t.Union[ + t.Callable[[], t.Optional[ResponseReturnValue]], + t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]], +] +ShellContextProcessorCallable = t.Callable[[], dict[str, t.Any]] +TeardownCallable = t.Union[ + t.Callable[[t.Optional[BaseException]], None], + t.Callable[[t.Optional[BaseException]], t.Awaitable[None]], +] +TemplateContextProcessorCallable = t.Union[ + t.Callable[[], dict[str, t.Any]], + t.Callable[[], t.Awaitable[dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, dict[str, t.Any]], None] +URLValuePreprocessorCallable = t.Callable[ + [t.Optional[str], t.Optional[dict[str, t.Any]]], None +] + +# This should take Exception, but that either breaks typing the argument +# with a specific exception, or decorating multiple times with different +# exceptions (and using a union type on the argument). +# https://github.com/pallets/flask/issues/4095 +# https://github.com/pallets/flask/issues/4295 +# https://github.com/pallets/flask/issues/4297 +ErrorHandlerCallable = t.Union[ + t.Callable[[t.Any], ResponseReturnValue], + t.Callable[[t.Any], t.Awaitable[ResponseReturnValue]], +] + +RouteCallable = t.Union[ + t.Callable[..., ResponseReturnValue], + t.Callable[..., t.Awaitable[ResponseReturnValue]], +] diff --git a/.venv/lib/python3.11/site-packages/flask/views.py b/.venv/lib/python3.11/site-packages/flask/views.py new file mode 100644 index 0000000..53fe976 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/views.py @@ -0,0 +1,191 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +http_method_funcs = frozenset( + ["get", "post", "head", "options", "delete", "put", "trace", "patch"] +) + + +class View: + """Subclass this class and override :meth:`dispatch_request` to + create a generic class-based view. Call :meth:`as_view` to create a + view function that creates an instance of the class with the given + arguments and calls its ``dispatch_request`` method with any URL + variables. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class Hello(View): + init_every_request = False + + def dispatch_request(self, name): + return f"Hello, {name}!" + + app.add_url_rule( + "/hello/", view_func=Hello.as_view("hello") + ) + + Set :attr:`methods` on the class to change what methods the view + accepts. + + Set :attr:`decorators` on the class to apply a list of decorators to + the generated view function. Decorators applied to the class itself + will not be applied to the generated view function! + + Set :attr:`init_every_request` to ``False`` for efficiency, unless + you need to store request-global data on ``self``. + """ + + #: The methods this view is registered for. Uses the same default + #: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and + #: ``add_url_rule`` by default. + methods: t.ClassVar[t.Collection[str] | None] = None + + #: Control whether the ``OPTIONS`` method is handled automatically. + #: Uses the same default (``True``) as ``route`` and + #: ``add_url_rule`` by default. + provide_automatic_options: t.ClassVar[bool | None] = None + + #: A list of decorators to apply, in order, to the generated view + #: function. Remember that ``@decorator`` syntax is applied bottom + #: to top, so the first decorator in the list would be the bottom + #: decorator. + #: + #: .. versionadded:: 0.8 + decorators: t.ClassVar[list[t.Callable[..., t.Any]]] = [] + + #: Create a new instance of this view class for every request by + #: default. If a view subclass sets this to ``False``, the same + #: instance is used for every request. + #: + #: A single instance is more efficient, especially if complex setup + #: is done during init. However, storing data on ``self`` is no + #: longer safe across requests, and :data:`~flask.g` should be used + #: instead. + #: + #: .. versionadded:: 2.2 + init_every_request: t.ClassVar[bool] = True + + def dispatch_request(self) -> ft.ResponseReturnValue: + """The actual view function behavior. Subclasses must override + this and return a valid response. Any variables from the URL + rule are passed as keyword arguments. + """ + raise NotImplementedError() + + @classmethod + def as_view( + cls, name: str, *class_args: t.Any, **class_kwargs: t.Any + ) -> ft.RouteCallable: + """Convert the class into a view function that can be registered + for a route. + + By default, the generated view will create a new instance of the + view class for every request and call its + :meth:`dispatch_request` method. If the view class sets + :attr:`init_every_request` to ``False``, the same instance will + be used for every request. + + Except for ``name``, all other arguments passed to this method + are forwarded to the view class ``__init__`` method. + + .. versionchanged:: 2.2 + Added the ``init_every_request`` class attribute. + """ + if cls.init_every_request: + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + self = view.view_class( # type: ignore[attr-defined] + *class_args, **class_kwargs + ) + return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return] + + else: + self = cls(*class_args, **class_kwargs) # pyright: ignore + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return] + + if cls.decorators: + view.__name__ = name + view.__module__ = cls.__module__ + for decorator in cls.decorators: + view = decorator(view) + + # We attach the view class to the view function for two reasons: + # first of all it allows us to easily figure out what class-based + # view this thing came from, secondly it's also used for instantiating + # the view class so you can actually replace it with something else + # for testing purposes and debugging. + view.view_class = cls # type: ignore + view.__name__ = name + view.__doc__ = cls.__doc__ + view.__module__ = cls.__module__ + view.methods = cls.methods # type: ignore + view.provide_automatic_options = cls.provide_automatic_options # type: ignore + return view + + +class MethodView(View): + """Dispatches request methods to the corresponding instance methods. + For example, if you implement a ``get`` method, it will be used to + handle ``GET`` requests. + + This can be useful for defining a REST API. + + :attr:`methods` is automatically set based on the methods defined on + the class. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class CounterAPI(MethodView): + def get(self): + return str(session.get("counter", 0)) + + def post(self): + session["counter"] = session.get("counter", 0) + 1 + return redirect(url_for("counter")) + + app.add_url_rule( + "/counter", view_func=CounterAPI.as_view("counter") + ) + """ + + def __init_subclass__(cls, **kwargs: t.Any) -> None: + super().__init_subclass__(**kwargs) + + if "methods" not in cls.__dict__: + methods = set() + + for base in cls.__bases__: + if getattr(base, "methods", None): + methods.update(base.methods) # type: ignore[attr-defined] + + for key in http_method_funcs: + if hasattr(cls, key): + methods.add(key.upper()) + + if methods: + cls.methods = methods + + def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue: + meth = getattr(self, request.method.lower(), None) + + # If the request method is HEAD and we don't have a handler for it + # retry with GET. + if meth is None and request.method == "HEAD": + meth = getattr(self, "get", None) + + assert meth is not None, f"Unimplemented method {request.method!r}" + return current_app.ensure_sync(meth)(**kwargs) # type: ignore[no-any-return] diff --git a/.venv/lib/python3.11/site-packages/flask/wrappers.py b/.venv/lib/python3.11/site-packages/flask/wrappers.py new file mode 100644 index 0000000..bab6102 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/flask/wrappers.py @@ -0,0 +1,257 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import HTTPException +from werkzeug.wrappers import Request as RequestBase +from werkzeug.wrappers import Response as ResponseBase + +from . import json +from .globals import current_app +from .helpers import _split_blueprint_path + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.routing import Rule + + +class Request(RequestBase): + """The request object used by default in Flask. Remembers the + matched endpoint and view arguments. + + It is what ends up as :class:`~flask.request`. If you want to replace + the request object used you can subclass this and set + :attr:`~flask.Flask.request_class` to your subclass. + + The request object is a :class:`~werkzeug.wrappers.Request` subclass and + provides all of the attributes Werkzeug defines plus a few Flask + specific ones. + """ + + json_module: t.Any = json + + #: The internal URL rule that matched the request. This can be + #: useful to inspect which methods are allowed for the URL from + #: a before/after handler (``request.url_rule.methods``) etc. + #: Though if the request's method was invalid for the URL rule, + #: the valid list is available in ``routing_exception.valid_methods`` + #: instead (an attribute of the Werkzeug exception + #: :exc:`~werkzeug.exceptions.MethodNotAllowed`) + #: because the request was never internally bound. + #: + #: .. versionadded:: 0.6 + url_rule: Rule | None = None + + #: A dict of view arguments that matched the request. If an exception + #: happened when matching, this will be ``None``. + view_args: dict[str, t.Any] | None = None + + #: If matching the URL failed, this is the exception that will be + #: raised / was raised as part of the request handling. This is + #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or + #: something similar. + routing_exception: HTTPException | None = None + + _max_content_length: int | None = None + _max_form_memory_size: int | None = None + _max_form_parts: int | None = None + + @property + def max_content_length(self) -> int | None: + """The maximum number of bytes that will be read during this request. If + this limit is exceeded, a 413 :exc:`~werkzeug.exceptions.RequestEntityTooLarge` + error is raised. If it is set to ``None``, no limit is enforced at the + Flask application level. However, if it is ``None`` and the request has + no ``Content-Length`` header and the WSGI server does not indicate that + it terminates the stream, then no data is read to avoid an infinite + stream. + + Each request defaults to the :data:`MAX_CONTENT_LENGTH` config, which + defaults to ``None``. It can be set on a specific ``request`` to apply + the limit to that specific view. This should be set appropriately based + on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This can be set per-request. + + .. versionchanged:: 0.6 + This is configurable through Flask config. + """ + if self._max_content_length is not None: + return self._max_content_length + + if not current_app: + return super().max_content_length + + return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] + + @max_content_length.setter + def max_content_length(self, value: int | None) -> None: + self._max_content_length = value + + @property + def max_form_memory_size(self) -> int | None: + """The maximum size in bytes any non-file form field may be in a + ``multipart/form-data`` body. If this limit is exceeded, a 413 + :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it + is set to ``None``, no limit is enforced at the Flask application level. + + Each request defaults to the :data:`MAX_FORM_MEMORY_SIZE` config, which + defaults to ``500_000``. It can be set on a specific ``request`` to + apply the limit to that specific view. This should be set appropriately + based on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This is configurable through Flask config. + """ + if self._max_form_memory_size is not None: + return self._max_form_memory_size + + if not current_app: + return super().max_form_memory_size + + return current_app.config["MAX_FORM_MEMORY_SIZE"] # type: ignore[no-any-return] + + @max_form_memory_size.setter + def max_form_memory_size(self, value: int | None) -> None: + self._max_form_memory_size = value + + @property # type: ignore[override] + def max_form_parts(self) -> int | None: + """The maximum number of fields that may be present in a + ``multipart/form-data`` body. If this limit is exceeded, a 413 + :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it + is set to ``None``, no limit is enforced at the Flask application level. + + Each request defaults to the :data:`MAX_FORM_PARTS` config, which + defaults to ``1_000``. It can be set on a specific ``request`` to apply + the limit to that specific view. This should be set appropriately based + on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This is configurable through Flask config. + """ + if self._max_form_parts is not None: + return self._max_form_parts + + if not current_app: + return super().max_form_parts + + return current_app.config["MAX_FORM_PARTS"] # type: ignore[no-any-return] + + @max_form_parts.setter + def max_form_parts(self, value: int | None) -> None: + self._max_form_parts = value + + @property + def endpoint(self) -> str | None: + """The endpoint that matched the request URL. + + This will be ``None`` if matching failed or has not been + performed yet. + + This in combination with :attr:`view_args` can be used to + reconstruct the same URL or a modified URL. + """ + if self.url_rule is not None: + return self.url_rule.endpoint # type: ignore[no-any-return] + + return None + + @property + def blueprint(self) -> str | None: + """The registered name of the current blueprint. + + This will be ``None`` if the endpoint is not part of a + blueprint, or if URL matching failed or has not been performed + yet. + + This does not necessarily match the name the blueprint was + created with. It may have been nested, or registered with a + different name. + """ + endpoint = self.endpoint + + if endpoint is not None and "." in endpoint: + return endpoint.rpartition(".")[0] + + return None + + @property + def blueprints(self) -> list[str]: + """The registered names of the current blueprint upwards through + parent blueprints. + + This will be an empty list if there is no current blueprint, or + if URL matching failed. + + .. versionadded:: 2.0.1 + """ + name = self.blueprint + + if name is None: + return [] + + return _split_blueprint_path(name) + + def _load_form_data(self) -> None: + super()._load_form_data() + + # In debug mode we're replacing the files multidict with an ad-hoc + # subclass that raises a different error for key errors. + if ( + current_app + and current_app.debug + and self.mimetype != "multipart/form-data" + and not self.files + ): + from .debughelpers import attach_enctype_error_multidict + + attach_enctype_error_multidict(self) + + def on_json_loading_failed(self, e: ValueError | None) -> t.Any: + try: + return super().on_json_loading_failed(e) + except BadRequest as ebr: + if current_app and current_app.debug: + raise + + raise BadRequest() from ebr + + +class Response(ResponseBase): + """The response object that is used by default in Flask. Works like the + response object from Werkzeug but is set to have an HTML mimetype by + default. Quite often you don't have to create this object yourself because + :meth:`~flask.Flask.make_response` will take care of that for you. + + If you want to replace the response object used you can subclass this and + set :attr:`~flask.Flask.response_class` to your subclass. + + .. versionchanged:: 1.0 + JSON support is added to the response, like the request. This is useful + when testing to get the test client response data as JSON. + + .. versionchanged:: 1.0 + + Added :attr:`max_cookie_size`. + """ + + default_mimetype: str | None = "text/html" + + json_module = json + + autocorrect_location_header = False + + @property + def max_cookie_size(self) -> int: # type: ignore + """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. + + See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in + Werkzeug's docs. + """ + if current_app: + return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2011 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/itsdangerous-2.2.0.dist-info/METADATA b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/METADATA new file mode 100644 index 0000000..ddf5464 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 2.2.0 +Summary: Safely pass data to untrusted environments and back. +Maintainer-email: Pallets +Requires-Python: >=3.8 +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 +Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://itsdangerous.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/itsdangerous/ + +# ItsDangerous + +... so better sign this + +Various helpers to pass data to untrusted environments and to get it +back safe and sound. Data is cryptographically signed to ensure that a +token has not been tampered with. + +It's possible to customize how data is serialized. Data is compressed as +needed. A timestamp can be added and verified automatically while +loading a token. + + +## A Simple Example + +Here's how you could generate a token for transmitting a user's id and +name between web requests. + +```python +from itsdangerous import URLSafeSerializer +auth_s = URLSafeSerializer("secret key", "auth") +token = auth_s.dumps({"id": 5, "name": "itsdangerous"}) + +print(token) +# eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg + +data = auth_s.loads(token) +print(data["name"]) +# itsdangerous +``` + + +## Donate + +The Pallets organization develops and supports ItsDangerous 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/itsdangerous-2.2.0.dist-info/RECORD b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/RECORD new file mode 100644 index 0000000..333875c --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/RECORD @@ -0,0 +1,22 @@ +itsdangerous-2.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +itsdangerous-2.2.0.dist-info/LICENSE.txt,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475 +itsdangerous-2.2.0.dist-info/METADATA,sha256=0rk0-1ZwihuU5DnwJVwPWoEI4yWOyCexih3JyZHblhE,1924 +itsdangerous-2.2.0.dist-info/RECORD,, +itsdangerous-2.2.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +itsdangerous/__init__.py,sha256=4SK75sCe29xbRgQE1ZQtMHnKUuZYAf3bSpZOrff1IAY,1427 +itsdangerous/__pycache__/__init__.cpython-311.pyc,, +itsdangerous/__pycache__/_json.cpython-311.pyc,, +itsdangerous/__pycache__/encoding.cpython-311.pyc,, +itsdangerous/__pycache__/exc.cpython-311.pyc,, +itsdangerous/__pycache__/serializer.cpython-311.pyc,, +itsdangerous/__pycache__/signer.cpython-311.pyc,, +itsdangerous/__pycache__/timed.cpython-311.pyc,, +itsdangerous/__pycache__/url_safe.cpython-311.pyc,, +itsdangerous/_json.py,sha256=wPQGmge2yZ9328EHKF6gadGeyGYCJQKxtU-iLKE6UnA,473 +itsdangerous/encoding.py,sha256=wwTz5q_3zLcaAdunk6_vSoStwGqYWe307Zl_U87aRFM,1409 +itsdangerous/exc.py,sha256=Rr3exo0MRFEcPZltwecyK16VV1bE2K9_F1-d-ljcUn4,3201 +itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous/serializer.py,sha256=PmdwADLqkSyQLZ0jOKAgDsAW4k_H0TlA71Ei3z0C5aI,15601 +itsdangerous/signer.py,sha256=YO0CV7NBvHA6j549REHJFUjUojw2pHqwcUpQnU7yNYQ,9647 +itsdangerous/timed.py,sha256=6RvDMqNumGMxf0-HlpaZdN9PUQQmRvrQGplKhxuivUs,8083 +itsdangerous/url_safe.py,sha256=az4e5fXi_vs-YbWj8YZwn4wiVKfeD--GEKRT5Ueu4P4,2505 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous-2.2.0.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/itsdangerous/__init__.py b/.venv/lib/python3.11/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..ea55256 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/__init__.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import typing as t + +from .encoding import base64_decode as base64_decode +from .encoding import base64_encode as base64_encode +from .encoding import want_bytes as want_bytes +from .exc import BadData as BadData +from .exc import BadHeader as BadHeader +from .exc import BadPayload as BadPayload +from .exc import BadSignature as BadSignature +from .exc import BadTimeSignature as BadTimeSignature +from .exc import SignatureExpired as SignatureExpired +from .serializer import Serializer as Serializer +from .signer import HMACAlgorithm as HMACAlgorithm +from .signer import NoneAlgorithm as NoneAlgorithm +from .signer import Signer as Signer +from .timed import TimedSerializer as TimedSerializer +from .timed import TimestampSigner as TimestampSigner +from .url_safe import URLSafeSerializer as URLSafeSerializer +from .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " ItsDangerous 2.3. Use feature detection or" + " 'importlib.metadata.version(\"itsdangerous\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("itsdangerous") + + raise AttributeError(name) diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/__init__.cpython-311.pyc b/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..53fc2e3a4bff77293807b91995854ac174eb5fea GIT binary patch literal 1987 zcmZ`(&2Jk;6rc6SdcF4Aj+5rAQMwICt`D(k8;~MZpg;;mq7fpkD(z*p_Dr0m`(e$F zle$VIgg8`OIB+P(aw#9>AK<^(R*_ikDH7t43o;5^a^lU{PO~J8pWpu8Z{EInZ|2SZ zplK?C@vHKn^KBNP-?=d!sUeV#{{-+9VT2_IxsoAC9H*R=k;ZA9aWZb!$O4zfS-`R( z3oHZ9899M-j^gHxyub=z)ldb_11=Z^fmOgoqbP6zux4li7Xg=ylE9i%b}L3j;F2@p zR*kB_Wx$ihq`(!xQ^u6Q6V4@f+L#u&3V6nt5qQ#>b?1yZfu{h^8}oqY@!VG#<1$Wd zqWa|{UVL4O3zp~k%wo3h1sg}wkkndMK;Bs~F=_jlfY+EH-iT0lEsvS4J|h84=iayQ zy2UJjd4P9_g$V^i1>;kz@Awu5s|ePn-SI5eqdaH@?0dFL65OeA`%%}Xgukb55^7tH z{aD1*?%ZAbV9n|H)Mnc*OlupyN6r#5k0E@^JUmXkE~tQ6Zuit{;{Io!Y+73+;Ws@Z z{}Un3c$Q1zbiimVQv#KECt225^ZISRcjE!AhSCU0$3FvjiuRzj9*TCO@8J|i4%(N* zQ`%4MrJju%as2Y|iPKDe&EU*0+2;`P1^kCYLVMEZnX&bZuXt`?`8j0u;xw~O#I)B= zdnh^krBu&t#0AsbAvAz~Fipxcd;I;qZKBuC&^6s+jM}XpBf1^vm~<&=TZ~}c^02;Z zJC5EWIwh{Z1Dx&YAG2WH@;Ze2y+FUwxY^L}2Snc@q7&eKM%ugqb)V`r+wJ<4Id-ez z5@uoOs>UdvYfCl@@Hoy=y#}EJ2EEoe;(78;frD*7bjS{I;^JB7dM>V>4;(AI7WHhe z6T}&g;_CXS6iDX5a4J^DX~elv9&u@HT>foJeOgb`X;?qbpRPc4umgTnx~`wxZTel- zY*Q$g?6}Ljq}7CyyqzW#+3fb&w(s3+T)*B7Y(|#5P=M7TLGx_-P1CeJo0(>#+vf+= zft`UA;DD~d8nb*c3hE0K{}us1mBo9h9&BR<6G)*MDrhEUzAvS3_m>4|Vptsh8^Ffw~xG z7LQ?7RL_X|=?q}Xlc95*U5HiF-0Jbm4vF&3h-KFA!gj|Jixu%H0fX|+rM%T?j{Bs^ zqc&BzndgdszG;E0B3Hb9;h0Z92(-irIS@CVmbpuXs|ikL8NdFt%85x%C_UW`Ov)juhGRKID`8TiqzSVT zYJ^FN&>LY=B2){L5}|sSln5<{Nr}+gVNxz)-U?AdB6K56%0M#G(8P&KE5$ literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/_json.cpython-311.pyc b/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/_json.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9417707b93ed734450952a13db042445ac1cee36 GIT binary patch literal 1364 zcmZ`&%}*0S6rb5I*0xX~9^_&+q9$vgMSCzY#6(Rr;ZP48FpbG(=nQ4C-CbvFH|JObtCoRNq9@*wGN$g*O{Di)wSoHGeAA z#Yvt7K`4pz!$4H)Cqe0=X9_-k0KyhxsD>%3X%yFVX3zq)HjN$d>}FwrH52T^GlPF@`Av|mc)L9l`;Iu;8ZZbzM5$OoY{YW^gOTJ_R zK4Yb1C?cI^NN6t)PG{X&=zuG+IFoH2^h{a0A9U()YJ;JQfEOR%1YrxwzkJIBc^&P5 zygSf=EUvm*VtR^GVyYd5i@60kgo<){v*j?7o7Zu$%5s3Vuc zpi;VZt1N)~6mWk|8cdXZDJTgV3hV}fQm};k61phx) zKif_i$&)@&nU@D`wvHCD4|(3H7T$_v^n#LsQdn-BqvxzIFTV2uGYhoJ$%>I zl~q!2yIlAaYvvzS{-MP7ynwWr=OsDM%Q_t7g6F+xljezM$n$7eS7xDZW4*cf$atg+2!nbiWhtLf&=F6zU; z-#4VLY*V!r)B)@l+i=sM60ZJwVyOF({U}RzB0p#(Sf<4I74ZLI+_Pu0y6^D`aHu;Z n2tZfI7$2ak@#%SpF2((MfX3qf>{@vYl+VMFvigJ@z}o literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/encoding.cpython-311.pyc b/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/encoding.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40638296076fce6f6dc9918370ae2da4be6d3303 GIT binary patch literal 2943 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/serializer.cpython-311.pyc b/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/serializer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd68055b5269aa177d1c64de2bd47a281e04551e GIT binary patch literal 15720 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 Bc18dI literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/signer.cpython-311.pyc b/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/signer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..094958638f3ff1d8f348176cb5ee89f9f1a74a9b GIT binary patch literal 12473 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/url_safe.cpython-311.pyc b/.venv/lib/python3.11/site-packages/itsdangerous/__pycache__/url_safe.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d4dccb9b878c5c9c22b6ee3c451562567cafa72 GIT binary patch literal 4125 zcmbVPU1%KF6~41Gv;RNR>Sv|evL}^{wIHwR*l~;EHt|pGCe%uZ6HK>+(P-yN8f$iD zduP_NmQ`ztOE)wvDY#St7epzpgZtozQrfq;(1$`FRz{FzKwv0&$lJQ|gYi?(xwAi7 z$^D71X3v~^?>Xn*d+s^k9Q{6#h!SXj3133z%OMo#=u|ib7rx zkPn!FyvW~DUeZNfGUZ}0AA~tkm(5TyoDXw82z(?T;e5!97GwDs=fh^an8+tM9|1m@ zPjWtLriy*}K7jPksBm=4zKIGc?nvPzGbso?hx*qe%7cP{BWk zPg}bsWHXrY+o^4 zm^4jAb6r|2xr%Em71NlHD$okxDn=bgahIs#xXiE?alWW6Q`B>oZ01s?7z>I;3m~Vl z)tvH1+o0*#+=}mE#dqj#Q;rQi%|%lM%~BjVfw`*8Q>A2T1%Ka~0!PbnGnJveuKzx4 z>3uJ)(*><;x@z}Oc(KuL*9(>W`}5@aRhK%Rq_IWkne67ySgR}ro_-eRyi!$WZHs!r z?}axTZnbpymrwAUfz4zTw+-K(8* zRD+8`Rs5~+4lzho`kn9#0U|s+dtnECm}BUHcPp=+v&*KgKz1vw;PTU#2UqK^A&v@K z*`bQPpg?fZ>jhduD1gvN+RRuqEX`CYV>YXt>6*jPSJ2q5!0#Gduo>mEI?n`1iq>2< z4Dse_%ylr)SP*vUMZVo$l7+D^p=~ePHSWnyxkQ;4M`%&omLi_yP;-Ixfew#NmPT#} z$r!hD)v+y4pk72(3#R5cs_NinV!~p(@$AyHU2>-jjA|~uRy?*s=cjYmsC8``HZWaU zb(d`GMDFwMdy=cBaeBR52fOrB!wqj912=4>7sjd(VKN z(+?N*^ag1r$?$<%^ieGRS#0cKY;0ZMjE!%_#+xJ%In)>)Ti4d-*XM67*Df|j$7*jj zrC?-edqCO9Yz}0%2C}vDwewH6QzK0xMTWX$JAJUxcd2n$Y0Bb2@-YGO1W7YU28Ws< zF){QMT2llie8)+AxJg2h(Pki+7~Resxb>qAcQZ4!m6`fT`bc`ZJ#Y|gCq}zudst}< zUTKU^zyg^xERadV0+}={Ffs}Y^pCa{NFW0X^iBM{{K3kHD_g1Yjq~-?%-xef{OA6u z78{;%j)80Lq)w4PMbBi!2PAzaEj~!g$d3)4d6_(TIeK ztCSmT0@aTK`H#u4dpBQ4^=m*N8Mae{7$cvh#vekMoZC!IZlxw`Qe$MSme?K|z4iXa z$<3k3t)asKUpF zv5Q<*^8M5uMeS_V3#+Q76{)IvQB^J4df7xiuBtyMYi4UEq^i1IP*sLO#gah0l&bEk z!(a;GguBs8v;eF?O;c5~g70#S-Pe6*Ipjt+uiyOt2Y#b(QnVj56b&2Uhknag#nxjALN>?#;t4t&dW1wq$=vJPr7ULf)M2;sV2q!pm# zH5?beQtaARYPfbgCg|Y%vy-Hz8V^9ghxG%)bXl7|io2Ra#Im!xL48G^)j;crJ z=BAK21`M|Yd=7ZOIGg=MVmUZ4n?~|AB*%e#LVPdr)OiI*k$eY!JD9)Ey-I$cNPJaP z_>vB8m&1Ds@yg$x=jA;@|IO9hKX7@xQhjk(b2E4+FX(D^3S7bvUv@cn2D?b!LgpKt zNgT=!VahI)p_YY|Wg-lDL3gzT;o%9c51X=zWd+Y$FU(7InB|2Ghfq(10*co$K6+rm z!SH`jPj>O&9fo-BiBOR9jNsSIx3g!T&%&pD==c^p2O5|x&IO=NQ4oX%`D(rQc|_9n z_R}D-8~pDPIb8338f3iQ`#f*tK%MkF4Ki8pefDo)|41` t.Any: + return _json.loads(payload) + + @staticmethod + def dumps(obj: t.Any, **kwargs: t.Any) -> str: + kwargs.setdefault("ensure_ascii", False) + kwargs.setdefault("separators", (",", ":")) + return _json.dumps(obj, **kwargs) diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/encoding.py b/.venv/lib/python3.11/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..f5ca80f --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/encoding.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import base64 +import string +import struct +import typing as t + +from .exc import BadData + + +def want_bytes( + s: str | bytes, encoding: str = "utf-8", errors: str = "strict" +) -> bytes: + if isinstance(s, str): + s = s.encode(encoding, errors) + + return s + + +def base64_encode(string: str | bytes) -> bytes: + """Base64 encode a string of bytes or text. The resulting bytes are + safe to use in URLs. + """ + string = want_bytes(string) + return base64.urlsafe_b64encode(string).rstrip(b"=") + + +def base64_decode(string: str | bytes) -> bytes: + """Base64 decode a URL-safe string of bytes or text. The result is + bytes. + """ + string = want_bytes(string, encoding="ascii", errors="ignore") + string += b"=" * (-len(string) % 4) + + try: + return base64.urlsafe_b64decode(string) + except (TypeError, ValueError) as e: + raise BadData("Invalid base64-encoded data") from e + + +# The alphabet used by base64.urlsafe_* +_base64_alphabet = f"{string.ascii_letters}{string.digits}-_=".encode("ascii") + +_int64_struct = struct.Struct(">Q") +_int_to_bytes = _int64_struct.pack +_bytes_to_int = t.cast("t.Callable[[bytes], tuple[int]]", _int64_struct.unpack) + + +def int_to_bytes(num: int) -> bytes: + return _int_to_bytes(num).lstrip(b"\x00") + + +def bytes_to_int(bytestr: bytes) -> int: + return _bytes_to_int(bytestr.rjust(8, b"\x00"))[0] diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/exc.py b/.venv/lib/python3.11/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..a75adcd --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/exc.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import typing as t +from datetime import datetime + + +class BadData(Exception): + """Raised if bad data of any sort was encountered. This is the base + for all exceptions that ItsDangerous defines. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str): + super().__init__(message) + self.message = message + + def __str__(self) -> str: + return self.message + + +class BadSignature(BadData): + """Raised if a signature does not match.""" + + def __init__(self, message: str, payload: t.Any | None = None): + super().__init__(message) + + #: The payload that failed the signature test. In some + #: situations you might still want to inspect this, even if + #: you know it was tampered with. + #: + #: .. versionadded:: 0.14 + self.payload: t.Any | None = payload + + +class BadTimeSignature(BadSignature): + """Raised if a time-based signature is invalid. This is a subclass + of :class:`BadSignature`. + """ + + def __init__( + self, + message: str, + payload: t.Any | None = None, + date_signed: datetime | None = None, + ): + super().__init__(message, payload) + + #: If the signature expired this exposes the date of when the + #: signature was created. This can be helpful in order to + #: tell the user how long a link has been gone stale. + #: + #: .. versionchanged:: 2.0 + #: The datetime value is timezone-aware rather than naive. + #: + #: .. versionadded:: 0.14 + self.date_signed = date_signed + + +class SignatureExpired(BadTimeSignature): + """Raised if a signature timestamp is older than ``max_age``. This + is a subclass of :exc:`BadTimeSignature`. + """ + + +class BadHeader(BadSignature): + """Raised if a signed header is invalid in some form. This only + happens for serializers that have a header that goes with the + signature. + + .. versionadded:: 0.24 + """ + + def __init__( + self, + message: str, + payload: t.Any | None = None, + header: t.Any | None = None, + original_error: Exception | None = None, + ): + super().__init__(message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header: t.Any | None = header + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: Exception | None = original_error + + +class BadPayload(BadData): + """Raised if a payload is invalid. This could happen if the payload + is loaded despite an invalid signature, or if there is a mismatch + between the serializer and deserializer. The original exception + that occurred during loading is stored on as :attr:`original_error`. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str, original_error: Exception | None = None): + super().__init__(message) + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: Exception | None = original_error diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/py.typed b/.venv/lib/python3.11/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/serializer.py b/.venv/lib/python3.11/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..5ddf387 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/serializer.py @@ -0,0 +1,406 @@ +from __future__ import annotations + +import collections.abc as cabc +import json +import typing as t + +from .encoding import want_bytes +from .exc import BadPayload +from .exc import BadSignature +from .signer import _make_keys_list +from .signer import Signer + +if t.TYPE_CHECKING: + import typing_extensions as te + + # This should be either be str or bytes. To avoid having to specify the + # bound type, it falls back to a union if structural matching fails. + _TSerialized = te.TypeVar( + "_TSerialized", bound=t.Union[str, bytes], default=t.Union[str, bytes] + ) +else: + # Still available at runtime on Python < 3.13, but without the default. + _TSerialized = t.TypeVar("_TSerialized", bound=t.Union[str, bytes]) + + +class _PDataSerializer(t.Protocol[_TSerialized]): + def loads(self, payload: _TSerialized, /) -> t.Any: ... + # A signature with additional arguments is not handled correctly by type + # checkers right now, so an overload is used below for serializers that + # don't match this strict protocol. + def dumps(self, obj: t.Any, /) -> _TSerialized: ... + + +# Use TypeIs once it's available in typing_extensions or 3.13. +def is_text_serializer( + serializer: _PDataSerializer[t.Any], +) -> te.TypeGuard[_PDataSerializer[str]]: + """Checks whether a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), str) + + +class Serializer(t.Generic[_TSerialized]): + """A serializer wraps a :class:`~itsdangerous.signer.Signer` to + enable serializing and securely signing data other than bytes. It + can unsign to verify that the data hasn't been changed. + + The serializer provides :meth:`dumps` and :meth:`loads`, similar to + :mod:`json`, and by default uses :mod:`json` internally to serialize + the data to bytes. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param serializer: An object that provides ``dumps`` and ``loads`` + methods for serializing data to a string. Defaults to + :attr:`default_serializer`, which defaults to :mod:`json`. + :param serializer_kwargs: Keyword arguments to pass when calling + ``serializer.dumps``. + :param signer: A ``Signer`` class to instantiate when signing data. + Defaults to :attr:`default_signer`, which defaults to + :class:`~itsdangerous.signer.Signer`. + :param signer_kwargs: Keyword arguments to pass when instantiating + the ``Signer`` class. + :param fallback_signers: List of signer parameters to try when + unsigning with the default signer fails. Each item can be a dict + of ``signer_kwargs``, a ``Signer`` class, or a tuple of + ``(signer, signer_kwargs)``. Defaults to + :attr:`default_fallback_signers`. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 2.0 + Removed the default SHA-512 fallback signer from + ``default_fallback_signers``. + + .. versionchanged:: 1.1 + Added support for ``fallback_signers`` and configured a default + SHA-512 fallback. This fallback is for users who used the yanked + 1.0.0 release which defaulted to SHA-512. + + .. versionchanged:: 0.14 + The ``signer`` and ``signer_kwargs`` parameters were added to + the constructor. + """ + + #: The default serialization module to use to serialize data to a + #: string internally. The default is :mod:`json`, but can be changed + #: to any object that provides ``dumps`` and ``loads`` methods. + default_serializer: _PDataSerializer[t.Any] = json + + #: The default ``Signer`` class to instantiate when signing data. + #: The default is :class:`itsdangerous.signer.Signer`. + default_signer: type[Signer] = Signer + + #: The default fallback signers to try when unsigning fails. + default_fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] = [] + + # Serializer[str] if no data serializer is provided, or if it returns str. + @t.overload + def __init__( + self: Serializer[str], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + serializer: None | _PDataSerializer[str] = None, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Serializer[bytes] with a bytes data serializer positional argument. + @t.overload + def __init__( + self: Serializer[bytes], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None, + serializer: _PDataSerializer[bytes], + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Serializer[bytes] with a bytes data serializer keyword argument. + @t.overload + def __init__( + self: Serializer[bytes], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + *, + serializer: _PDataSerializer[bytes], + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Fall back with a positional argument. If the strict signature of + # _PDataSerializer doesn't match, fall back to a union, requiring the user + # to specify the type. + @t.overload + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None, + serializer: t.Any, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Fall back with a keyword argument. + @t.overload + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + *, + serializer: t.Any, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + serializer: t.Any | None = None, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: list[bytes] = _make_keys_list(secret_key) + + if salt is not None: + salt = want_bytes(salt) + # if salt is None then the signer's default is used + + self.salt = salt + + if serializer is None: + serializer = self.default_serializer + + self.serializer: _PDataSerializer[_TSerialized] = serializer + self.is_text_serializer: bool = is_text_serializer(serializer) + + if signer is None: + signer = self.default_signer + + self.signer: type[Signer] = signer + self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {} + + if fallback_signers is None: + fallback_signers = list(self.default_fallback_signers) + + self.fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] = fallback_signers + self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {} + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def load_payload( + self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None + ) -> t.Any: + """Loads the encoded object. This function raises + :class:`.BadPayload` if the payload is not valid. The + ``serializer`` parameter can be used to override the serializer + stored on the class. The encoded ``payload`` should always be + bytes. + """ + if serializer is None: + use_serializer = self.serializer + is_text = self.is_text_serializer + else: + use_serializer = serializer + is_text = is_text_serializer(serializer) + + try: + if is_text: + return use_serializer.loads(payload.decode("utf-8")) # type: ignore[arg-type] + + return use_serializer.loads(payload) # type: ignore[arg-type] + except Exception as e: + raise BadPayload( + "Could not load the payload because an exception" + " occurred on unserializing the data.", + original_error=e, + ) from e + + def dump_payload(self, obj: t.Any) -> bytes: + """Dumps the encoded object. The return value is always bytes. + If the internal serializer returns text, the value will be + encoded as UTF-8. + """ + return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) + + def make_signer(self, salt: str | bytes | None = None) -> Signer: + """Creates a new instance of the signer to be used. The default + implementation uses the :class:`.Signer` base class. + """ + if salt is None: + salt = self.salt + + return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs) + + def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]: + """Iterates over all signers to be tried for unsigning. Starts + with the configured signer, then constructs each signer + specified in ``fallback_signers``. + """ + if salt is None: + salt = self.salt + + yield self.make_signer(salt) + + for fallback in self.fallback_signers: + if isinstance(fallback, dict): + kwargs = fallback + fallback = self.signer + elif isinstance(fallback, tuple): + fallback, kwargs = fallback + else: + kwargs = self.signer_kwargs + + for secret_key in self.secret_keys: + yield fallback(secret_key, salt=salt, **kwargs) + + def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized: + """Returns a signed string serialized with the internal + serializer. The return value can be either a byte or unicode + string depending on the format of the internal serializer. + """ + payload = want_bytes(self.dump_payload(obj)) + rv = self.make_signer(salt).sign(payload) + + if self.is_text_serializer: + return rv.decode("utf-8") # type: ignore[return-value] + + return rv # type: ignore[return-value] + + def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None: + """Like :meth:`dumps` but dumps into a file. The file handle has + to be compatible with what the internal serializer expects. + """ + f.write(self.dumps(obj, salt)) + + def loads( + self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any + ) -> t.Any: + """Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the + signature validation fails. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + return self.load_payload(signer.unsign(s)) + except BadSignature as err: + last_exception = err + + raise t.cast(BadSignature, last_exception) + + def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any: + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe( + self, s: str | bytes, salt: str | bytes | None = None + ) -> tuple[bool, t.Any]: + """Like :meth:`loads` but without verifying the signature. This + is potentially very dangerous to use depending on how your + serializer works. The return value is ``(signature_valid, + payload)`` instead of just the payload. The first item will be a + boolean that indicates if the signature is valid. This function + never fails. + + Use it for debugging only and if you know that your serializer + module is not exploitable (for example, do not use it with a + pickle serializer). + + .. versionadded:: 0.15 + """ + return self._loads_unsafe_impl(s, salt) + + def _loads_unsafe_impl( + self, + s: str | bytes, + salt: str | bytes | None, + load_kwargs: dict[str, t.Any] | None = None, + load_payload_kwargs: dict[str, t.Any] | None = None, + ) -> tuple[bool, t.Any]: + """Low level helper function to implement :meth:`loads_unsafe` + in serializer subclasses. + """ + if load_kwargs is None: + load_kwargs = {} + + try: + return True, self.loads(s, salt=salt, **load_kwargs) + except BadSignature as e: + if e.payload is None: + return False, None + + if load_payload_kwargs is None: + load_payload_kwargs = {} + + try: + return ( + False, + self.load_payload(e.payload, **load_payload_kwargs), + ) + except BadPayload: + return False, None + + def load_unsafe( + self, f: t.IO[t.Any], salt: str | bytes | None = None + ) -> tuple[bool, t.Any]: + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), salt=salt) diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/signer.py b/.venv/lib/python3.11/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..e324dc0 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/signer.py @@ -0,0 +1,266 @@ +from __future__ import annotations + +import collections.abc as cabc +import hashlib +import hmac +import typing as t + +from .encoding import _base64_alphabet +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import want_bytes +from .exc import BadSignature + + +class SigningAlgorithm: + """Subclasses must implement :meth:`get_signature` to provide + signature generation functionality. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + """Returns the signature for the given key and value.""" + raise NotImplementedError() + + def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool: + """Verifies the given signature matches the expected + signature. + """ + return hmac.compare_digest(sig, self.get_signature(key, value)) + + +class NoneAlgorithm(SigningAlgorithm): + """Provides an algorithm that does not perform any signing and + returns an empty signature. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + return b"" + + +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + +class HMACAlgorithm(SigningAlgorithm): + """Provides signature generation using HMACs.""" + + #: The digest method to use with the MAC algorithm. This defaults to + #: SHA1, but can be changed to any other function in the hashlib + #: module. + default_digest_method: t.Any = staticmethod(_lazy_sha1) + + def __init__(self, digest_method: t.Any = None): + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: t.Any = digest_method + + def get_signature(self, key: bytes, value: bytes) -> bytes: + mac = hmac.new(key, msg=value, digestmod=self.digest_method) + return mac.digest() + + +def _make_keys_list( + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], +) -> list[bytes]: + if isinstance(secret_key, (str, bytes)): + return [want_bytes(secret_key)] + + return [want_bytes(s) for s in secret_key] # pyright: ignore + + +class Signer: + """A signer securely signs bytes, then unsigns them to verify that + the value hasn't been changed. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param sep: Separator between the signature and value. + :param key_derivation: How to derive the signing key from the secret + key and salt. Possible values are ``concat``, ``django-concat``, + or ``hmac``. Defaults to :attr:`default_key_derivation`, which + defaults to ``django-concat``. + :param digest_method: Hash function to use when generating the HMAC + signature. Defaults to :attr:`default_digest_method`, which + defaults to :func:`hashlib.sha1`. Note that the security of the + hash alone doesn't apply when used intermediately in HMAC. + :param algorithm: A :class:`SigningAlgorithm` instance to use + instead of building a default :class:`HMACAlgorithm` with the + ``digest_method``. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 0.18 + ``algorithm`` was added as an argument to the class constructor. + + .. versionchanged:: 0.14 + ``key_derivation`` and ``digest_method`` were added as arguments + to the class constructor. + """ + + #: The default digest method to use for the signer. The default is + #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or + #: compatible object. Note that the security of the hash alone + #: doesn't apply when used intermediately in HMAC. + #: + #: .. versionadded:: 0.14 + default_digest_method: t.Any = staticmethod(_lazy_sha1) + + #: The default scheme to use to derive the signing key from the + #: secret key and salt. The default is ``django-concat``. Possible + #: values are ``concat``, ``django-concat``, and ``hmac``. + #: + #: .. versionadded:: 0.14 + default_key_derivation: str = "django-concat" + + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous.Signer", + sep: str | bytes = b".", + key_derivation: str | None = None, + digest_method: t.Any | None = None, + algorithm: SigningAlgorithm | None = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: list[bytes] = _make_keys_list(secret_key) + self.sep: bytes = want_bytes(sep) + + if self.sep in _base64_alphabet: + raise ValueError( + "The given separator cannot be used because it may be" + " contained in the signature itself. ASCII letters," + " digits, and '-_=' must not be used." + ) + + if salt is not None: + salt = want_bytes(salt) + else: + salt = b"itsdangerous.Signer" + + self.salt = salt + + if key_derivation is None: + key_derivation = self.default_key_derivation + + self.key_derivation: str = key_derivation + + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: t.Any = digest_method + + if algorithm is None: + algorithm = HMACAlgorithm(self.digest_method) + + self.algorithm: SigningAlgorithm = algorithm + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def derive_key(self, secret_key: str | bytes | None = None) -> bytes: + """This method is called to derive the key. The default key + derivation choices can be overridden here. Key derivation is not + intended to be used as a security method to make a complex key + out of a short password. Instead you should use large random + secret keys. + + :param secret_key: A specific secret key to derive from. + Defaults to the last item in :attr:`secret_keys`. + + .. versionchanged:: 2.0 + Added the ``secret_key`` parameter. + """ + if secret_key is None: + secret_key = self.secret_keys[-1] + else: + secret_key = want_bytes(secret_key) + + if self.key_derivation == "concat": + return t.cast(bytes, self.digest_method(self.salt + secret_key).digest()) + elif self.key_derivation == "django-concat": + return t.cast( + bytes, self.digest_method(self.salt + b"signer" + secret_key).digest() + ) + elif self.key_derivation == "hmac": + mac = hmac.new(secret_key, digestmod=self.digest_method) + mac.update(self.salt) + return mac.digest() + elif self.key_derivation == "none": + return secret_key + else: + raise TypeError("Unknown key derivation method") + + def get_signature(self, value: str | bytes) -> bytes: + """Returns the signature for the given value.""" + value = want_bytes(value) + key = self.derive_key() + sig = self.algorithm.get_signature(key, value) + return base64_encode(sig) + + def sign(self, value: str | bytes) -> bytes: + """Signs the given string.""" + value = want_bytes(value) + return value + self.sep + self.get_signature(value) + + def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool: + """Verifies the signature for the given value.""" + try: + sig = base64_decode(sig) + except Exception: + return False + + value = want_bytes(value) + + for secret_key in reversed(self.secret_keys): + key = self.derive_key(secret_key) + + if self.algorithm.verify_signature(key, value, sig): + return True + + return False + + def unsign(self, signed_value: str | bytes) -> bytes: + """Unsigns the given string.""" + signed_value = want_bytes(signed_value) + + if self.sep not in signed_value: + raise BadSignature(f"No {self.sep!r} found in value") + + value, sig = signed_value.rsplit(self.sep, 1) + + if self.verify_signature(value, sig): + return value + + raise BadSignature(f"Signature {sig!r} does not match", payload=value) + + def validate(self, signed_value: str | bytes) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid. + """ + try: + self.unsign(signed_value) + return True + except BadSignature: + return False diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/timed.py b/.venv/lib/python3.11/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..7384375 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/timed.py @@ -0,0 +1,228 @@ +from __future__ import annotations + +import collections.abc as cabc +import time +import typing as t +from datetime import datetime +from datetime import timezone + +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import bytes_to_int +from .encoding import int_to_bytes +from .encoding import want_bytes +from .exc import BadSignature +from .exc import BadTimeSignature +from .exc import SignatureExpired +from .serializer import _TSerialized +from .serializer import Serializer +from .signer import Signer + + +class TimestampSigner(Signer): + """Works like the regular :class:`.Signer` but also records the time + of the signing and can be used to expire signatures. The + :meth:`unsign` method can raise :exc:`.SignatureExpired` if the + unsigning failed because the signature is expired. + """ + + def get_timestamp(self) -> int: + """Returns the current timestamp. The function must return an + integer. + """ + return int(time.time()) + + def timestamp_to_datetime(self, ts: int) -> datetime: + """Convert the timestamp from :meth:`get_timestamp` into an + aware :class`datetime.datetime` in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + return datetime.fromtimestamp(ts, tz=timezone.utc) + + def sign(self, value: str | bytes) -> bytes: + """Signs the given string and also attaches time information.""" + value = want_bytes(value) + timestamp = base64_encode(int_to_bytes(self.get_timestamp())) + sep = want_bytes(self.sep) + value = value + sep + timestamp + return value + sep + self.get_signature(value) + + # Ignore overlapping signatures check, return_timestamp is the only + # parameter that affects the return type. + + @t.overload + def unsign( # type: ignore[overload-overlap] + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: t.Literal[False] = False, + ) -> bytes: ... + + @t.overload + def unsign( + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: t.Literal[True] = True, + ) -> tuple[bytes, datetime]: ... + + def unsign( + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: bool = False, + ) -> tuple[bytes, datetime] | bytes: + """Works like the regular :meth:`.Signer.unsign` but can also + validate the time. See the base docstring of the class for + the general behavior. If ``return_timestamp`` is ``True`` the + timestamp of the signature will be returned as an aware + :class:`datetime.datetime` object in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + try: + result = super().unsign(signed_value) + sig_error = None + except BadSignature as e: + sig_error = e + result = e.payload or b"" + + sep = want_bytes(self.sep) + + # If there is no timestamp in the result there is something + # seriously wrong. In case there was a signature error, we raise + # that one directly, otherwise we have a weird situation in + # which we shouldn't have come except someone uses a time-based + # serializer on non-timestamp data, so catch that. + if sep not in result: + if sig_error: + raise sig_error + + raise BadTimeSignature("timestamp missing", payload=result) + + value, ts_bytes = result.rsplit(sep, 1) + ts_int: int | None = None + ts_dt: datetime | None = None + + try: + ts_int = bytes_to_int(base64_decode(ts_bytes)) + except Exception: + pass + + # Signature is *not* okay. Raise a proper error now that we have + # split the value and the timestamp. + if sig_error is not None: + if ts_int is not None: + try: + ts_dt = self.timestamp_to_datetime(ts_int) + except (ValueError, OSError, OverflowError) as exc: + # Windows raises OSError + # 32-bit raises OverflowError + raise BadTimeSignature( + "Malformed timestamp", payload=value + ) from exc + + raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt) + + # Signature was okay but the timestamp is actually not there or + # malformed. Should not happen, but we handle it anyway. + if ts_int is None: + raise BadTimeSignature("Malformed timestamp", payload=value) + + # Check timestamp is not older than max_age + if max_age is not None: + age = self.get_timestamp() - ts_int + + if age > max_age: + raise SignatureExpired( + f"Signature age {age} > {max_age} seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if age < 0: + raise SignatureExpired( + f"Signature age {age} < 0 seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if return_timestamp: + return value, self.timestamp_to_datetime(ts_int) + + return value + + def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid.""" + try: + self.unsign(signed_value, max_age=max_age) + return True + except BadSignature: + return False + + +class TimedSerializer(Serializer[_TSerialized]): + """Uses :class:`TimestampSigner` instead of the default + :class:`.Signer`. + """ + + default_signer: type[TimestampSigner] = TimestampSigner + + def iter_unsigners( + self, salt: str | bytes | None = None + ) -> cabc.Iterator[TimestampSigner]: + return t.cast("cabc.Iterator[TimestampSigner]", super().iter_unsigners(salt)) + + # TODO: Signature is incompatible because parameters were added + # before salt. + + def loads( # type: ignore[override] + self, + s: str | bytes, + max_age: int | None = None, + return_timestamp: bool = False, + salt: str | bytes | None = None, + ) -> t.Any: + """Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the + signature validation fails. If a ``max_age`` is provided it will + ensure the signature is not older than that time in seconds. In + case the signature is outdated, :exc:`.SignatureExpired` is + raised. All arguments are forwarded to the signer's + :meth:`~TimestampSigner.unsign` method. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + base64d, timestamp = signer.unsign( + s, max_age=max_age, return_timestamp=True + ) + payload = self.load_payload(base64d) + + if return_timestamp: + return payload, timestamp + + return payload + except SignatureExpired: + # The signature was unsigned successfully but was + # expired. Do not try the next signer. + raise + except BadSignature as err: + last_exception = err + + raise t.cast(BadSignature, last_exception) + + def loads_unsafe( # type: ignore[override] + self, + s: str | bytes, + max_age: int | None = None, + salt: str | bytes | None = None, + ) -> tuple[bool, t.Any]: + return self._loads_unsafe_impl(s, salt, load_kwargs={"max_age": max_age}) diff --git a/.venv/lib/python3.11/site-packages/itsdangerous/url_safe.py b/.venv/lib/python3.11/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..56a0793 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/itsdangerous/url_safe.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import typing as t +import zlib + +from ._json import _CompactJSON +from .encoding import base64_decode +from .encoding import base64_encode +from .exc import BadPayload +from .serializer import _PDataSerializer +from .serializer import Serializer +from .timed import TimedSerializer + + +class URLSafeSerializerMixin(Serializer[str]): + """Mixed in with a regular serializer it will attempt to zlib + compress the string to make it shorter if necessary. It will also + base64 encode the string so that it can safely be placed in a URL. + """ + + default_serializer: _PDataSerializer[str] = _CompactJSON + + def load_payload( + self, + payload: bytes, + *args: t.Any, + serializer: t.Any | None = None, + **kwargs: t.Any, + ) -> t.Any: + decompress = False + + if payload.startswith(b"."): + payload = payload[1:] + decompress = True + + try: + json = base64_decode(payload) + except Exception as e: + raise BadPayload( + "Could not base64 decode the payload because of an exception", + original_error=e, + ) from e + + if decompress: + try: + json = zlib.decompress(json) + except Exception as e: + raise BadPayload( + "Could not zlib decompress the payload before decoding the payload", + original_error=e, + ) from e + + return super().load_payload(json, *args, **kwargs) + + def dump_payload(self, obj: t.Any) -> bytes: + json = super().dump_payload(obj) + is_compressed = False + compressed = zlib.compress(json) + + if len(compressed) < (len(json) - 1): + json = compressed + is_compressed = True + + base64d = base64_encode(json) + + if is_compressed: + base64d = b"." + base64d + + return base64d + + +class URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]): + """Works like :class:`.Serializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + + +class URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]): + """Works like :class:`.TimedSerializer` but dumps and loads into a + URL safe string consisting of the upper and lowercase character of + the alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/INSTALLER b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/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-3.1.4.dist-info/METADATA b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/METADATA new file mode 100644 index 0000000..265cc32 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/METADATA @@ -0,0 +1,76 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.4 +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 +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 + +.. code-block:: 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 + diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/RECORD b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/RECORD new file mode 100644 index 0000000..e7ac0c5 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/RECORD @@ -0,0 +1,57 @@ +jinja2-3.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.4.dist-info/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2-3.1.4.dist-info/METADATA,sha256=R_brzpPQVBvpGcsm-WbrtgotO7suQ1D0F-qkhTzeEfY,2640 +jinja2-3.1.4.dist-info/RECORD,, +jinja2-3.1.4.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +jinja2-3.1.4.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2/__init__.py,sha256=wIl45IM20KGw-kfr7jJhaBxxX5g4-kihlBYjxopX7Pw,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=JXKWCAXmTx0iZB4-hAsF50vgjxw_RJTjiLOlGGTBso0,2477 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=dpV-n6_iQUP4uSwlXwGUavJmwjvXdyxKzJ-AonFjPBk,72271 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=xhFkmxO0CESA76Ki5tz4XWq9yzGu-t0p93JCCVBVNps,61538 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=igsBH7c6C0byHaOtMbE-ugpt4GjLGgR-ywskyXtKgq8,31877 +jinja2/filters.py,sha256=bKeqjFjjz88TkHVLSyyMIEB75CzAN6b3Airgx0phJDg,54611 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=xnWWXhPndHFsoqzpc5VTjheDE9JuKk9MUo9DZkrM8Os,29754 +jinja2/loaders.py,sha256=ru0GIWHo5KiHJi7_MoI_LvGDoBBvP6rd0hiC1ReaTwk,23167 +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=DV1iF1FR2Rsaj_5zl8rmx7j6Bj4S8iLHoYsvJ0bfEis,39890 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=POXT3tKNKJRENx2CymwUsOOXH2JwGPjW702njB5__cQ,33435 +jinja2/sandbox.py,sha256=TJjBNS9qRJ2ZgBMWdAgRBpyDLOHea2kT-2mk4PrjYx0,14616 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=nV7IpWLvRCMyHW1irBAK8CIPAnOFfkb2ukggDBjbBEY,23952 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/WHEEL b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.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/jinja2-3.1.4.dist-info/entry_points.txt b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.dist-info/entry_points.txt new file mode 100644 index 0000000..abc3eae --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2-3.1.4.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/__init__.py b/.venv/lib/python3.11/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..2f0b5b2 --- /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.4" 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..fe3bcb5e8ad4784fd8e60633439567a2999d2815 GIT binary patch literal 2113 zcma)+$!^<57{^DJWJ%Ow$=2fCw4Jmt0!eU_Za^BK-jWn?VAL&I%!Q!HslN_T1DwGb$yqn+E#gJVi@-UYlbmz& zUI7;*=Ych>NiF~vaZ$1cT*4*EMc^_nOD+Lda7A(%cnL2_uDDgNhHH|SfS2*I)*d|{1>L~Fx}KS@j}<+L??dV@rnM5I-C<8s^ru`8X)tnZ06tHy;Rby;GkpU#igP2-MPb8d3{5mL zwun5mjOK+~5F);Hv?!z`q%5QYGRe8}?J>F}tg4WjkYyn&Lh3>qLYg3x9KAU}v?Z)n zA!|a`g=~OKvP15;jBW~JOUSm69U;1qU64u9Fh+!mt7aH~qBmfnw~xDU+qxDdaJffb z`xWVRJ0noPTLOPYXMnW`{dJv)e^AV%Rks2{Njns(MCeS=a?MRInJ&Dwa(Pxnw zF?txO5u=kxjTk+O)QHhhq(+Rsh}5`kK8F!f;`NMtwJVHvu=w75ojJlB;|Ibmng;8R4;jj-MI)7IhKNrQ1-h&hMA12O#XaE2J 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..85a37bc941148fafa96699a751dba117623e1a68 GIT binary patch literal 2129 zcmX|?&2uA18OCM1U=va~a^u7;P`$3efeXbSz<~<~ssa?{tVQs$>vegZP36SsTWfn_ zjlC;bwk3@<`kEPyN79VGtdUg38FI*By&H$@+wzINc&O!+6HikFseb)F{l3riyge<| zG~a#qdl7ubZ~f+@#+^vyMozx{to%>BxeHN~sy2`xF zv6m;W_Smb+tIl&fH2>=R6n4)hESk-mFfmHVvHIIY6R3k zwV9-5hMHMw?qQ-*vp~%%H4SRcs0C*$L9KvVaGG&4Gh}ATgws^X)X40R*(I}27Mxas ztbi;y?G)J=gr{V~YO7>d$u`JFPxhSJ@U|1w4yX;UlO!iYPL>>49hICsIR$d6Y&_BQWxcJmbxf+Rq8&cZl1bT>KfF;&3Xyy1=NGp zOOgkxmn9EYPbKd;d3o}x1#_Bq8O@S3OVcbvGZm8p&2YxEfaYng*o-SP9?LTxEAm(wLFch5LXF3o z2o8^R5qutxGagrY{D8+#ph{dVF|Jnl*&*X+&-hsn!RMtzUOM8X9xr*k>@!|D;*}ED z_ZZhzUQO|8npaI;(;2VXyw*XO@K%BG)+sliGj5i-iJBR3bIvW4ttoFSjJK1#jn$ka zchIoo@e3p`;{4(q!QpO$ao6LW8snWI_i~JThunLH(BhuMJ@n@J+#4c{`4E>55he)p zg)(2nltt{>B9UW@#MvTozDU%eI*a7-B6+d!T(X zm{SJ~!)2Jme-%Rlq(B<%%ftZ~Ng*w`&aQ(-nDc8$`pqymO+!p`p{6JdLma@b#nNC7 z5l1H8k>WDclG2kzCfSt254BVZz?JqB~Q=#5@f( zYZt;QhFVA7t}_7gcAa^s^$sC=O<+oalHY~!rNAA0?AV_I`JDTBkbSH>kjo7|12~g` z299I`+n>ljCWA0@Ym-l|VTxrRofW2^=YU0J|vR zluGH86nnsu!U;=H;}B1iVX1|KDYXVbn$0%ohb0RY>l6vA0?wsy!?OI{l$A8dN^uO} zDJ$o|05yOED=Su5HgXU~J}lRh5cS1%O0I{{U zvlHFkG$U{1yY-u2u0Gn@S-rO%UE7I1dB{GAezVu6BSGPXh`O~A#pWc1{ z{nf`CJ5jc^cJI$?A4MOp-rv}~zxI>WKWwZ=H+MGvxDnmHyY=ZeZ~gq?qxFv;M1QgU zHkOtz^T!NBxU#gg^fL0c^51Xx-N-xN&;D@#N8xhhJAe7XzgCvtS^jqfgK|fHxACfv F{0G&!|2hBw literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/jinja2/__pycache__/async_utils.cpython-311.pyc b/.venv/lib/python3.11/site-packages/jinja2/__pycache__/async_utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d521f2cd9ec77b729e26fe63d09901801076ef6 GIT binary patch literal 4565 zcmbss?{5>yb;i5vUE6V-A0&qSph*Z^eZ8}jkRJz!Xq*xd$2FoP4KxV(Hr`Ee&R+Xw z*CB);<#f5?oKTfhLF5BS`9Nt9cM>1zx3=mZu&(x0Yo$n$TBP1LS5c)CpZaFkzX{h< zJ3IS!-prdfGw;{D{k_-gMo|7BT%P~hh0xzAQY_X8AbSEv=mCqXKgS&Ptv&cE;~Q_9Hb) zKEMx3F3BsoflrCNk`K&k0ID_#PohB6x0L@x0GrL1FNH5&9KRF^PfngcH}UiFiK$8G z=57!%rG86K2AB}JD5`3h%tN~|1ffJw0| z&`nq+jmSX>Yjl-DSzwDT$)OeP1G+#$%o_Uzr}%#`Jxl2&?zTho7I`A1`6}8C<#x3N zY?Z92Oo7mfqnfH3yUl1NdqHTOUtzv-K7o@yE1kA#9JopRSHcre#xtrAt7K4y%Q!RC zid<{L6X<(Z7(u8SyUngUiBI#FhS3UJvmaJ+udtE2BE<>|>h(;RtVrfn(@A74O_VBS zb3ke-`$K5FNy%DCK_C!t*pfY?h0-yqk3ET=IwlB}LVz`~X0lOH1vr~b#!VrnMnv_d z5`Bt^2Pjl(OkJ-&2qjZmC`x2elNS^3-jHWQ!9`hF48>!!q0~+7dQv$a?C%e$F-?9q zB}P9M=Vdjt5K|V!fsn;7lGb8zHJG|dsG%K zcNKR;C84$hSVcSjgZCC6Nn2;O8y}xDdIz)qA;UkUHw^8;Fxp>+(=hV?$gu1PwbCT@ zz&gMYYRQC}Flhu}dO$ugl2j71qFIL~)(I?uk^_|Nf0e{Rn5-TK@R}q>jNZ|#KWzBJ zdPA5{^A9klI}%AGrF2}5L?Adt6fr?tb&<#?X)$hNG;Benip?vs^b~>)p>j6)bV>q+ zOHn{dg&O6L;N7DFz0W>?2)53ypc-3utaHRo%~3+1S48C7;AKRB8O#cbp%wfX{|15_ z;Lb`Mf*zsEkPZL=-ZDhf`SA_QQShwkwvA^ltwb#unvIGqOVwf4qa;ZJ!Y(CJdEnF4 z)wK%6lDx^&h@Fzja{mvv!@`sv;HCZwz;~-C??jDxr)ZI0S?nEt^vT0CmGAJ^2dvM&z>U3QxJWsMZPGDJX=`9T>Ntya;owe3_wSB;bL>R6 z=cLhd@^3xkf9)C9&rWB1E*m|UvmIBAjw`UAm#+HEE&b@Q?i$IuMhw@;4sHB)byitQ#2OBEzYg-K)kM_sn5d#l7xLNG+HAoVB!YQm0VoIj8D0T(f< zYth*Q)*2=UIZRq6bZS+6r8f2%ynFuuZ~@_(7+V_{G`h7ySwy5oqkdi}<@-v)Fb^op zSM?;)DpG)j(yUtkr2P#X9km=kgB11_GmRcFzlMwW4YT&yM}V0i)ZUltwP5&$7}Lbr zxO{c`TEJSU`gE2PD|^(Y4D|OIomR5v<&LL*Qzl1(o=VLc;m=MI_v2)Je@k* zX`6rmmph@Sef72${G}30Dpx@SG+8)b7yvQ6)1?I~&}*-nDrw+i2b$Lmhyh*iW#Dl8 z84&ypRG9)fs?kVSDCOK$dQHUx=y-*aY4&>=fxTluQ>nSZT58A2K-U?X;(R^ zEK^Luf+~%gwkC8>Xy3YtGvUesOHQ9VeQW?*3MIpoPdT|W>nax}<1qRQNuw5K(d~YvF{F8J1q#XmW7cMz{U#3rV|2COqsWn1Q$(x zG)U@ID>JaN0h6=Ra4WO0GXs7KV%D@ste9rq4ki;*G?SZ)Cq>OpG8k1OCQAiqvQjLn zk+&c-ey;yT7pjX!%YS*jlZZ!&{In=9H*Im}T8eTh}iGDh%93 zoXjH_d7)aLTF@$Bf3E&yo`LT!cPP)nm(o;%RtERwJR^AqzPp@rZ94O_wX1m!usnJL Humt)apTilu literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/jinja2/__pycache__/bccache.cpython-311.pyc b/.venv/lib/python3.11/site-packages/jinja2/__pycache__/bccache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..801888878fa910880bbbe17417f96efa625abbb8 GIT binary patch literal 20911 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 DI*M`u 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..9518946927dc61f7d07b14e83d0be59776a939c1 GIT binary patch literal 110495 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 A#{d8T 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..62e50e45bbac106d0d6c5d8a5816864edff6da8f GIT binary patch literal 1548 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 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/jinja2/__pycache__/defaults.cpython-311.pyc b/.venv/lib/python3.11/site-packages/jinja2/__pycache__/defaults.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a9fc9d71bed08451d32b776cee6f66a11f63d20 GIT binary patch literal 1714 zcmaJ>%}*Og6rc4M{=mkcd?z6gN-csd(yD5u(8`#Fx)?*SY1(b7)y6ZBh4tEPQ zYAW>);DA&P9Jp2a6Z&5)QV**+Me2#0D{h?ncJU@ys=9uD`+IMG^WK{`Gy6w08bp(B5Js3&kicON_9~u+SMYHNuut(f0>XfU{YtPA5<(6R z01gXb2M+*_2oVPd0S^j;93tF))J;ZxPV|^CghN6chlK==2uVCBq;OP7bj*c_jNzfDU;$_Re>ic6lMp6wLYTx!;T}%G%yiFtpFAK_BuqjiLI!c>JRm&8 z!*~R9@Ee8y7#@~6oWSGfL17xQ%(&^vC|HkNYuD3P*TijIRg|5)vMH4-=qAc?Y+$ui zuJPMdfc_d^t=S+@?9>%P0j2kdN~ok0QE5`r5apKEZrF@(nlcOk3RR>A(OOcS7@pU& zhG+H|-meYMvHhMgJTu2EQ!Z6_v05wC_zk{N6Subc)zWt?<+zKR8+V+mH(c1buajI^ z)*-L*!`usX?(x*z3+le-eq`|q|NJ&2|7?e^6!~m``KhGt5$3~kU1tHssgnij&N^6N z->H^`RJYa|3#!d#%U;}-9~!|zT9fMH0qJPjppmRM8!Z_+kdw5!EQ^{>jc}VPvO#i` zC`Po0b&2i~-AMOL^0Q7QQLDcq&=F%ur){+kt;;Ed97!D`wXZeR9BwySnz#!?y4+Na z#2x3s5yaDsIK;`xi=V4Goyv^{!7RSQuNHR7(7DZWsaWEx*;y9QJ1tq=W1P+gc4Y;+ zrBS##hz+^q-o`S&PBdMk&N8F!ptIG?-_~VCqXC#l2W%Czm3`w_wD$cLFBZS%i|eJz z8cW=!6QMSuYEZexJUU^?{@P z(45&X|HYX!QJ=i?`hNSWi#Tq^@=cqrbOUI397?iMBPNPlqcA07*`Aa&GGU^$m4WO@ zE4u*xlb=qFi<#43Oa#`#C0elN=7D(f>{Ph$o{A;{YyJ|=Td~xeh!xMgiCSMQK~yvO znTY@_U7{sx^d3a&hEXhK4aTk5v=vL+k{Its2Qr>60%f8^cNk4Pu#%II-kO}UMn)|# y$7e5ebL=sM=q5rR0~Zv8KY4ii(OK$DIwxo2exW6~$E75@UEOYvF& 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..167e7a1c07da8e96bd93c23e24f27920b1b8ebf6 GIT binary patch literal 80693 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 Az5oCK literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/jinja2/__pycache__/exceptions.cpython-311.pyc b/.venv/lib/python3.11/site-packages/jinja2/__pycache__/exceptions.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb20e3f8ec160954f5cc58b494603e2431e57b4b GIT binary patch literal 8599 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 Pst!%;tm+Pl$<2QQ@;P*w 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..15cf0e49bd8a1532378be577c24e3beae1104b6d GIT binary patch literal 43366 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 V>O0n)zwM3}cahz3&>!3F{XeMzi6Q_1 literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/jinja2/__pycache__/filters.cpython-311.pyc b/.venv/lib/python3.11/site-packages/jinja2/__pycache__/filters.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1b03eb70e138a9f2d08e2d202bc633bc7976de9 GIT binary patch literal 77325 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 B0gnIx literal 0 HcmV?d00001 diff --git a/.venv/lib/python3.11/site-packages/jinja2/__pycache__/lexer.cpython-311.pyc b/.venv/lib/python3.11/site-packages/jinja2/__pycache__/lexer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..221098e29bb6f43d5a219f69a2cbc8ef42426184 GIT binary patch literal 35609 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 t`Ncl@+G@7rnPmG9HF9ROncdm_ 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 H<81veNH>}j 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..351641490d4af223ce670c4bd4c6d7641908631e GIT binary patch literal 7955 zcmb_B{cjt`m9yL>#qUpjShkw1CAl?Io3dib_9adVx&Ek~L~bI-*YMJ#*W8svgF=VC1KJ zZ=@`R9fXCBuz{3hRm#`-ac(;xB+X#^(P~T&JcBYvY zh&*=)4@)>1O%EPyNUZR?UNOo4rsepKLT0WP>s?aG#1zNpG&n?d@ zU&3Y(BvgyCqG9uQ0cnt6%SkE~SjSmO%V^THlA+2xg_ghxbumYaYC%zT`1GDr3iEkM zS4byND0*A0~d%6epdMaC_idYU*<}j z=8|1gM7I?S$V!}(O6Ff<{i#^uWTCm4mtA_7%@=yPbZ_&^IjZI=!5Hds2R+f5n%C#$ zm?e$sp(d{qS0YY+mx=7&Y#F;rD|@cMs*jTopz5PWwR1g}T|T168jVD6C@ro+?z-u9 zj^^w=MTUspP;El=-WE$62w)IpoXX<96Z`m7@6bDAy|r^RfsFrUjSvdHu+C7z!4i%^h+D%wI`7jqi0 z(sJrdUSUN0#GI~)OoOn^QXxf7iD#h`UCL?7KJ3oeFs7nJ6&Od&g6hGPU@S=!HJt)W z4F_x;EGwzvMMY%CLl&2E`Yhw~)bxUyed>aw>8aL}bb*azQ$KP_ja69#J7(^;#(+Vk zg0(R1De*KO*o&}c5K?hLpI?AQ>&4b}q*%8vQGq8ZDkw$NB#z^R%8yF0wGY5GG6O2~ z!`Nl6^;oqZil4i##;3@KSUQ2aprz)Qzw#eNML;EZ zc4fEKma(=fbu?ehN_p*BKx~pdFahl`0IQ_jo3ftG-S27}qd#AKXR%SW1r)>->b6cO zfWb4{9l%I*Rf#g}Gu*rD$!afZzV}Xs=FCTBK%R zYFX8#OZATzltPg%vyUWCBdqhRBFQFCr6mnHfHKovSRZmMk0zlGTp-aN09Yjt;v^V- z*R#I3@p>h?+lcP21O|=3;Og#tP z$!?&rd6HK8rtJqlKIrWMN9~upl)zlDF@jeK$v!1Khx^P*+n8S2551y)xtAQ6_R2w^ zjs2ChA)t-R0dVSJGcn2Rs>2VjNE2WhWJR2@owv9&o6F9Ec~oVEYOO|C6E7}U z7EO~~a2jkrX+W-#R#PW)n>dwiMRtL2`S;FS-vF6FlP*)h@Qn^Z zC;ZTq{4_n#HYGEj**5aZH~+dBK8?J-4Pceri6qvKT|4!QQ}sE$4DZUoK?7j-n9)5} ziHsYO@v?W^+G_#bx#^z9c+>RS>XStiZ5PDZ-v2ispo`q5-QswcTyqUQaPI46!4WSC z&Q>ka8t2V5Mt0hnH#t4f9InLasFC&3v{%kZjJis~6e;nYW4}_{Jf;Xu0mG!%^g_(d zcHi`(zsqFxOB4+j^#L&brwj8%P0K+XK?kuSXvg5kC0&B(AN3~breoOS5CS}9^az4y z0chwB!Gqa8thcf4v$?#S(TmpDD^EOf>m9U=?L}a_N@^Yw>$w*CMQB5LPpw4v8`1r1 z?k^$(8!tB<*`7P`J|jL@i4Pm`;c{^Ji$Kr1eEozmkg5bmjKB!Gv;Jyg$J+CEBYkhb z@zxs~N+mLEM25@WVWu^c4*fvgVEXYqAfO-o9K5aaqk$6XY#myuocaJ)L$G%EWBUQ2 z60gy$>0Y7``+O*LlB`4MZ%mj#_8hR$PzjhEgWXq;mIFi8VD#-X zZ=G4c^iHV~95#X|G3%-E1kk_`lSyZh90O);BI)}&k-+5(4$w!9L(~*R(lz-Nm!uQG zj2_21I@jAY9M(dLn*J9IM}zJ~JiU{KX_WAx@YLz>_o4^&rPWpp(U=RS0UyXpUU^pkO8?>`~cp-;2y z)ebxX_nvBZ|2q&cBKEC)*89i_sS2mc!l}EvQe|OBHPpZM z>c;*`Xs;34yLuA;ERkVfhsbRIw6zE=%_v*p(}K*kM#+zixIGwgLyY~m^l(EDuj~Qg zcbQ>J__l{K1Πj_9=|d~XjsF%-l=eCvPNq`^|bdwX#tjkp{nE#BvT)@Hpf^F9b$ z=NduermaH`b})kAsHlIGc&9cwzgSYGB^?B*lL1JbkY*sz+2uP!inc@xCmjPr@e+&e zS^C0OL`)IPQ?PMaMeLM-vGW})qGw*{?@zKIo4+s7(wGe4KlvU>STv0Ux zEuGBhtfb1|W)!>Gjs;!;J{0dICJ&KXn{R}4D6(GZaUO(}RgE!|_EP}h{=y`ZxE+4% zR`{{&`sTUv<6}3@1AwOz9yh|{cw=|_4p$R>Mk0ATao|?sKsDNZJG$pqbkAnC5`Dsm zK5>tCb%*a00N`Lk;fIhWi1veH@EvXf#$f1nV(eC8tdclnBo38>^#@Z6hw&1R*~VY* zn+TK7!b1~d{AUL_fQ~y69@MwtxAi^H+2;s{K?Z5YUCl^bi?qhx?IFgSkSpzcFm;S| z>!tMQBaZPbE1R~>vn$w}-2+MI1KEDepKQy-{yW5h|Hhvu*Z3cAi`F5pir40PX_x@J zf^4>|pi$Yzzs&^jlPgEgL6)>d?ZhQWY~sb<%FS8%OGtJut633~U_gr*MLFfz9<*t{ zgx}U60Bd_NOL(wlIhag`tf2pp9q3w@dl$v5iOH$kZ>u96RXD@u(&>s?0!A#F{WJM9 zD0n&gOvh*A#r0Tg13N(f;fV-IKb3GU-kfF)Vg_GYQ1x8F%G%Lap^^R&!M`HF<4iLM zE+D|8MbRU+9mrt)tg~sa?0UqSD0VggSo4Quoe_E5i0rKq-WR?Tf2;8A1nC{$IV&lsH~_K!T{|9N!cY4X|AL&tXWpNky8 z4xtT;OqhTtQKDxNCD*tQf@=m^@_s zTk^m@xYbd;Sj=lIPi!TV-7J}HWsfl*WZen8^?z(ob|tVb2kc&sYD)26Ks1ct`v_1_ zruQs!BvPIQe=I^|Q67_#8MZxq-61)J`IYymb+LJtYQPKZEYYq51S`#PRT3}TPn8Um zollkYl$}qN>?%8-PQ4y46UTFxB+AaGN`}hLrxWMxG{a@$c&cP~+4C!Ha%A|)GKm>PEVGBH-Twh}R#A2U 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..bcfd5acefaa339c20f5382ab74f446cb7ae72673 GIT binary patch literal 64474 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 K??<=03vK{?eJ}+8 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..d092b72dabc3a33948d87542dcf83190f30b7fbc GIT binary patch literal 2844 zcmb7G|7#q_6`$GLTixyHBw0RHvK^eEk*!>toT}I^ZEf1xu97&#N{I!# z-tJ{)Pbaw-&<}#D;1*LH6hcZxFpi50&5vmb{ULvW6b>R50*3sQ-!3Qy;h*~6tnQ?1 z^GoM;-_E?5dGp@qeVO|ppEn7#e`bEUC=Eisz(KdcShc+k_-qoFl!;4S&8KC}O}Vbj>ImlyI#&aIlLA17-|AQ_GgKuxfzoRdp85yBRm@nnyVm!_BSh<(x)d zA@1Nhar4}GkRs#}yh$q$y4np=9J2pG37KEwEUZUf&AZJ7i-gA|i$dmvfsE`RVwKQ$ z8DFUjE~N)dW(O{-g|1gwWfAPXd}H490#^5Jhcg)h&yJWEF}V~rVCMp764#q;$f%7c4R_sDz?sN1%gJ0nRp^uvYhc zkiBFpr7IrjrW6Pp(F?4}nPUei)D3&`4s2C|BrGwTU}cHD915_~uGM}10`tSL&KiLT zeIJiT-GZrzHA8U=3`!JFrn##YOS7r0U9y)svl)O>;erEts68(+1X+fDLusEZ1z>C@ zIhgA*xe7L~0Qj7nN_`oH0z@OeUHe7D=dxsei7uS`5*$a0G)@Ph%O!M%=b$q$>_8$) zTmUOK8!USw3~Hc9tmDEs#}8QogEBS*j~XIyG!%Q#Z~|jxZym@ciSVq0)}jw!^r**q zON)9@MM$+LCF({z?5pa%-P%^V+dukkk$$NUK+dC{EQnNk`!|Rnh6Z1W*pdgxf@d+f zAcg>^kkz?B%ONxv#BJm`-Jn*EHW{=98`nbkAgo8sPgn|1_;AYZP%*yIb-C6K>7?RyK;_0?!8 z49=BiW~Mmx9mkOr>kC2wO_)mNfwsst8u0`8U@(}c;yU`HS)wD$42o`|^X=UEZT;Glqr-X%{ARL6b>jgP)>S|f^uUVmLfOPH%c8{S;=gW3U#yVgJtNg&~g@BmlHWS zMgjJ8JSx2oHim)i|LRC^{#s;V$y{FyqW4t{qUD>UMO(yzUea8GF)>%9N^DV!b;JTmYA;_}bdk2S_vstNBdyeZ`X~Apje1ZM zu=ATUr#~Zvl_h=adJ?vdhJx%5Pj89*TP=VFUiy8%O5q>7$W z?eALuopOUb*RNCWhMFWIMafMP=uNVcx=EU}MZtfmIf1?c?-@{Jc@QSf%*AQhfMkyI zi#*`Mb1ap3u?gv?ZX|~vq~$E!Npbor-c#{VMT9l05k#T^ca0loY-vG;LkgptmE_pG zR;!0_hb{QLm=@#6SGkPVi<3a&tYtaAEv02iL=+O5t*J;7r(t+|{4j|6bbA&i#qBk+4o-C$xXF$Qyr4Y zj&-zw{MhH?&)oanXX7)Uj?e5CCN{7C`TE28?QdV)n%sKx{?yjghtW>qQoC?z_tdlR zUEF1pZT7v+0GW8{E22+~evPC<^kbv@PfSuc(LVlMhtT}kA=w=%+|@fN;O+14qqc>O zoWv6IugjS$De_5b_{v!7lL7@=)D>`I3}%xQEt;59fnDR46`Pg?e*@rFg8raoz1gt+ zWJXNj2CSW82+1IjICVK#RWQc+1C$-^`<4Ysd9 z0IQ!E$I^w}!ijsYbyC=ydj5VR>HXk`AE#CCadzm=$xa$(JLLZ$Ni9HKiuriJvfR)C zYmI0X|B@tzC6>kmDojHmFmmGj{LNp?T3274z54TObFU;YVrnLUAl#}f{*5FDV6}Rh zxs<^9V}XSp@sR%p0=}ZOqh+WLAp)d8=<#hbnmmsQ^!uJ&GP&LVJWlEBKLNyOaaVtS wyZ`AJI=yiB!o43s%+L!DudB~T{Nt+X{5KgIqX6IklDorSA@}QVm{Rur2Q@*u!~g&Q 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..e8f69ba8d494b74af4cc6c825ee23afe81bf3248 GIT binary patch literal 59631 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�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 LX$c!p%=-U7+fDj! 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..f011ecb2c28180144640fdcbf33465c54f8a6b2c GIT binary patch literal 18914 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

    O-)bZ^=9OGyzuMTpY+ttDeOLlMFI^s8n$LP# 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 HR2csY=dFQj 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..44d304fe677c33080c7b287036c6527b72cdc5dc GIT binary patch literal 37116 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 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 t.cast("V", value) + + +async def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + async for item in t.cast("t.AsyncIterable[V]", iterable): + yield item + else: + for item in iterable: + yield item + + +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..2740717 --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2/compiler.py @@ -0,0 +1,1960 @@ +"""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(t.cast(F, new_func), f) + + +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) -> "Frame": + """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) -> "Frame": + """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(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, 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( + "async for event in parent_template.root_render_func(context):" + ) + self.indent() + self.writeline("yield event") + self.outdent() + 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"{self.choose_async()}for event in" + f" context.blocks[{node.name!r}][0]({context}):", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + + 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() + + skip_event_yield = False + if node.with_context: + self.writeline( + f"{self.choose_async()}for event in template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)})):" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + else: + self.writeline("yield from template._get_default_module()._body_stream") + skip_event_yield = True + + if not skip_event_yield: + self.indent() + self.simple_write("event", frame) + self.outdent() + + 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() + message = ( + "the template {included_template.__name__!r}" + f" (imported on {self.position(node)})" + 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() + 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: + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.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.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..7ed7e92 --- /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..1d3be0b --- /dev/null +++ b/.venv/lib/python3.11/site-packages/jinja2/environment.py @@ -0,0 +1,1675 @@ +"""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: "Environment") -> "Environment": + """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 = False, + ) -> "Environment": + """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.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( # type: ignore + 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 = "