From 375fbb3a7a513aefe91b780f7da1dd88e598a68c Mon Sep 17 00:00:00 2001 From: Tykayn Date: Tue, 4 Mar 2025 15:47:44 +0100 Subject: [PATCH] :zap: - sauvegarde automatique de l'avancement du livre --- app.py | 80 + data.json | 3 + index.html | 95 + livre.org | 4 + requirements.txt | 1 + static/css/style.css | 132 + static/js/main.js | 159 + templates/index.html | 58 + 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 -> 11211 bytes .../__pycache__/override.cpython-311.pyc | Bin 0 -> 368 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 -> 659 bytes .../__pycache__/_utilities.cpython-311.pyc | Bin 0 -> 3144 bytes .../blinker/__pycache__/base.cpython-311.pyc | Bin 0 -> 23676 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.8.dist-info/INSTALLER | 1 + .../click-8.1.8.dist-info/LICENSE.txt | 28 + .../click-8.1.8.dist-info/METADATA | 74 + .../click-8.1.8.dist-info/RECORD | 38 + .../site-packages/click-8.1.8.dist-info/WHEEL | 4 + .../site-packages/click/__init__.py | 75 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 3778 bytes .../click/__pycache__/_compat.cpython-311.pyc | Bin 0 -> 28720 bytes .../__pycache__/_termui_impl.cpython-311.pyc | Bin 0 -> 33321 bytes .../__pycache__/_textwrap.cpython-311.pyc | Bin 0 -> 2690 bytes .../__pycache__/_winconsole.cpython-311.pyc | Bin 0 -> 13380 bytes .../click/__pycache__/core.cpython-311.pyc | Bin 0 -> 142609 bytes .../__pycache__/decorators.cpython-311.pyc | Bin 0 -> 26382 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 16398 bytes .../__pycache__/formatting.cpython-311.pyc | Bin 0 -> 15735 bytes .../click/__pycache__/globals.cpython-311.pyc | Bin 0 -> 3400 bytes .../click/__pycache__/parser.cpython-311.pyc | Bin 0 -> 23179 bytes .../shell_completion.cpython-311.pyc | Bin 0 -> 24175 bytes .../click/__pycache__/termui.cpython-311.pyc | Bin 0 -> 34524 bytes .../click/__pycache__/testing.cpython-311.pyc | Bin 0 -> 26015 bytes .../click/__pycache__/types.cpython-311.pyc | Bin 0 -> 53758 bytes .../click/__pycache__/utils.cpython-311.pyc | Bin 0 -> 28086 bytes .../python3.11/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 788 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../python3.11/site-packages/click/core.py | 3047 ++++++ .../site-packages/click/decorators.py | 562 ++ .../site-packages/click/exceptions.py | 296 + .../site-packages/click/formatting.py | 301 + .../python3.11/site-packages/click/globals.py | 67 + .../python3.11/site-packages/click/parser.py | 531 + .../python3.11/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 603 ++ .../python3.11/site-packages/click/termui.py | 784 ++ .../python3.11/site-packages/click/testing.py | 483 + .../python3.11/site-packages/click/types.py | 1093 +++ .../python3.11/site-packages/click/utils.py | 624 ++ .../site-packages/distutils-precedence.pth | 1 + .../flask-3.0.2.dist-info/INSTALLER | 1 + .../flask-3.0.2.dist-info/LICENSE.rst | 28 + .../flask-3.0.2.dist-info/METADATA | 116 + .../flask-3.0.2.dist-info/RECORD | 58 + .../flask-3.0.2.dist-info/REQUESTED | 0 .../site-packages/flask-3.0.2.dist-info/WHEEL | 4 + .../flask-3.0.2.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 -> 3222 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 311 bytes .../flask/__pycache__/app.cpython-311.pyc | Bin 0 -> 63747 bytes .../__pycache__/blueprints.cpython-311.pyc | Bin 0 -> 4341 bytes .../flask/__pycache__/cli.cpython-311.pyc | Bin 0 -> 46926 bytes .../flask/__pycache__/config.cpython-311.pyc | Bin 0 -> 17300 bytes .../flask/__pycache__/ctx.cpython-311.pyc | Bin 0 -> 20952 bytes .../__pycache__/debughelpers.cpython-311.pyc | Bin 0 -> 10263 bytes .../flask/__pycache__/globals.cpython-311.pyc | Bin 0 -> 2274 bytes .../flask/__pycache__/helpers.cpython-311.pyc | Bin 0 -> 25991 bytes .../flask/__pycache__/logging.cpython-311.pyc | Bin 0 -> 3504 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 0 -> 17437 bytes .../flask/__pycache__/signals.cpython-311.pyc | Bin 0 -> 1415 bytes .../__pycache__/templating.cpython-311.pyc | Bin 0 -> 10702 bytes .../flask/__pycache__/testing.cpython-311.pyc | Bin 0 -> 14764 bytes .../flask/__pycache__/typing.cpython-311.pyc | Bin 0 -> 3878 bytes .../flask/__pycache__/views.cpython-311.pyc | Bin 0 -> 7507 bytes .../__pycache__/wrappers.cpython-311.pyc | Bin 0 -> 6858 bytes .../lib/python3.11/site-packages/flask/app.py | 1488 +++ .../site-packages/flask/blueprints.py | 91 + .../lib/python3.11/site-packages/flask/cli.py | 1111 +++ .../python3.11/site-packages/flask/config.py | 372 + .../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 | 621 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6926 bytes .../json/__pycache__/provider.cpython-311.pyc | Bin 0 -> 10041 bytes .../json/__pycache__/tag.cpython-311.pyc | Bin 0 -> 16634 bytes .../site-packages/flask/json/provider.py | 215 + .../site-packages/flask/json/tag.py | 326 + .../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 -> 35466 bytes .../__pycache__/blueprints.cpython-311.pyc | Bin 0 -> 32602 bytes .../__pycache__/scaffold.cpython-311.pyc | Bin 0 -> 31837 bytes .../site-packages/flask/sansio/app.py | 968 ++ .../site-packages/flask/sansio/blueprints.py | 632 ++ .../site-packages/flask/sansio/scaffold.py | 805 ++ .../site-packages/flask/sessions.py | 371 + .../python3.11/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 219 + .../python3.11/site-packages/flask/testing.py | 298 + .../python3.11/site-packages/flask/typing.py | 90 + .../python3.11/site-packages/flask/views.py | 191 + .../site-packages/flask/wrappers.py | 174 + .../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 -> 2044 bytes .../__pycache__/_json.cpython-311.pyc | Bin 0 -> 1421 bytes .../__pycache__/encoding.cpython-311.pyc | Bin 0 -> 3000 bytes .../__pycache__/exc.cpython-311.pyc | Bin 0 -> 4871 bytes .../__pycache__/serializer.cpython-311.pyc | Bin 0 -> 15777 bytes .../__pycache__/signer.cpython-311.pyc | Bin 0 -> 12530 bytes .../__pycache__/timed.cpython-311.pyc | Bin 0 -> 9797 bytes .../__pycache__/url_safe.cpython-311.pyc | Bin 0 -> 4182 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.5.dist-info/INSTALLER | 1 + .../jinja2-3.1.5.dist-info/LICENSE.txt | 28 + .../jinja2-3.1.5.dist-info/METADATA | 75 + .../jinja2-3.1.5.dist-info/RECORD | 57 + .../jinja2-3.1.5.dist-info/WHEEL | 4 + .../jinja2-3.1.5.dist-info/entry_points.txt | 3 + .../site-packages/jinja2/__init__.py | 38 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2170 bytes .../__pycache__/_identifier.cpython-311.pyc | Bin 0 -> 2186 bytes .../__pycache__/async_utils.cpython-311.pyc | Bin 0 -> 5646 bytes .../__pycache__/bccache.cpython-311.pyc | Bin 0 -> 20968 bytes .../__pycache__/compiler.cpython-311.pyc | Bin 0 -> 112490 bytes .../__pycache__/constants.cpython-311.pyc | Bin 0 -> 1605 bytes .../jinja2/__pycache__/debug.cpython-311.pyc | Bin 0 -> 6765 bytes .../__pycache__/defaults.cpython-311.pyc | Bin 0 -> 1771 bytes .../__pycache__/environment.cpython-311.pyc | Bin 0 -> 80628 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8656 bytes .../jinja2/__pycache__/ext.cpython-311.pyc | Bin 0 -> 43432 bytes .../__pycache__/filters.cpython-311.pyc | Bin 0 -> 77908 bytes .../__pycache__/idtracking.cpython-311.pyc | Bin 0 -> 19560 bytes .../jinja2/__pycache__/lexer.cpython-311.pyc | Bin 0 -> 35713 bytes .../__pycache__/loaders.cpython-311.pyc | Bin 0 -> 34446 bytes .../jinja2/__pycache__/meta.cpython-311.pyc | Bin 0 -> 5750 bytes .../__pycache__/nativetypes.cpython-311.pyc | Bin 0 -> 8012 bytes .../jinja2/__pycache__/nodes.cpython-311.pyc | Bin 0 -> 64531 bytes .../__pycache__/optimizer.cpython-311.pyc | Bin 0 -> 2901 bytes .../jinja2/__pycache__/parser.cpython-311.pyc | Bin 0 -> 60077 bytes .../__pycache__/runtime.cpython-311.pyc | Bin 0 -> 51164 bytes .../__pycache__/sandbox.cpython-311.pyc | Bin 0 -> 19272 bytes .../jinja2/__pycache__/tests.cpython-311.pyc | Bin 0 -> 9321 bytes .../jinja2/__pycache__/utils.cpython-311.pyc | Bin 0 -> 37608 bytes .../__pycache__/visitor.cpython-311.pyc | Bin 0 -> 5749 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 99 + .../site-packages/jinja2/bccache.py | 408 + .../site-packages/jinja2/compiler.py | 1998 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.11/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1672 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../python3.11/site-packages/jinja2/ext.py | 870 ++ .../site-packages/jinja2/filters.py | 1878 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.11/site-packages/jinja2/lexer.py | 868 ++ .../site-packages/jinja2/loaders.py | 693 ++ .../python3.11/site-packages/jinja2/meta.py | 112 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.11/site-packages/jinja2/nodes.py | 1206 +++ .../site-packages/jinja2/optimizer.py | 48 + .../python3.11/site-packages/jinja2/parser.py | 1049 ++ .../python3.11/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1062 ++ .../site-packages/jinja2/sandbox.py | 436 + .../python3.11/site-packages/jinja2/tests.py | 256 + .../python3.11/site-packages/jinja2/utils.py | 766 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 395 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 25787 bytes .../__pycache__/_native.cpython-311.pyc | Bin 0 -> 738 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 -> 823 bytes .../pip/__pycache__/__main__.cpython-311.pyc | Bin 0 -> 1132 bytes .../__pip-runner__.cpython-311.pyc | Bin 0 -> 2560 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1006 bytes .../__pycache__/build_env.cpython-311.pyc | Bin 0 -> 16126 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 14751 bytes .../__pycache__/configuration.cpython-311.pyc | Bin 0 -> 19282 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 38411 bytes .../__pycache__/main.cpython-311.pyc | Bin 0 -> 806 bytes .../__pycache__/pyproject.cpython-311.pyc | Bin 0 -> 5574 bytes .../self_outdated_check.cpython-311.pyc | Bin 0 -> 11376 bytes .../__pycache__/wheel_builder.cpython-311.pyc | Bin 0 -> 16046 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 -> 341 bytes .../autocompletion.cpython-311.pyc | Bin 0 -> 10131 bytes .../__pycache__/base_command.cpython-311.pyc | Bin 0 -> 11129 bytes .../__pycache__/cmdoptions.cpython-311.pyc | Bin 0 -> 33028 bytes .../command_context.cpython-311.pyc | Bin 0 -> 2163 bytes .../cli/__pycache__/main.cpython-311.pyc | Bin 0 -> 2418 bytes .../__pycache__/main_parser.cpython-311.pyc | Bin 0 -> 5577 bytes .../cli/__pycache__/parser.cpython-311.pyc | Bin 0 -> 17078 bytes .../__pycache__/progress_bars.cpython-311.pyc | Bin 0 -> 3225 bytes .../__pycache__/req_command.cpython-311.pyc | Bin 0 -> 20190 bytes .../cli/__pycache__/spinners.cpython-311.pyc | Bin 0 -> 8890 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 0 -> 429 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 -> 4509 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 10608 bytes .../__pycache__/check.cpython-311.pyc | Bin 0 -> 2359 bytes .../__pycache__/completion.cpython-311.pyc | Bin 0 -> 5521 bytes .../__pycache__/configuration.cpython-311.pyc | Bin 0 -> 14950 bytes .../__pycache__/debug.cpython-311.pyc | Bin 0 -> 12058 bytes .../__pycache__/download.cpython-311.pyc | Bin 0 -> 7865 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 0 -> 4210 bytes .../commands/__pycache__/hash.cpython-311.pyc | Bin 0 -> 3411 bytes .../commands/__pycache__/help.cpython-311.pyc | Bin 0 -> 2023 bytes .../__pycache__/index.cpython-311.pyc | Bin 0 -> 7846 bytes .../__pycache__/inspect.cpython-311.pyc | Bin 0 -> 4499 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 35428 bytes .../commands/__pycache__/list.cpython-311.pyc | Bin 0 -> 17560 bytes .../__pycache__/search.cpython-311.pyc | Bin 0 -> 9005 bytes .../commands/__pycache__/show.cpython-311.pyc | Bin 0 -> 11348 bytes .../__pycache__/uninstall.cpython-311.pyc | Bin 0 -> 5199 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 10005 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 -> 1091 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 2463 bytes .../__pycache__/installed.cpython-311.pyc | Bin 0 -> 1600 bytes .../__pycache__/sdist.cpython-311.pyc | Bin 0 -> 9002 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 2194 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 -> 295 bytes .../__pycache__/collector.cpython-311.pyc | Bin 0 -> 24601 bytes .../package_finder.cpython-311.pyc | Bin 0 -> 44273 bytes .../index/__pycache__/sources.cpython-311.pyc | Bin 0 -> 11077 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 -> 18233 bytes .../__pycache__/_distutils.cpython-311.pyc | Bin 0 -> 7642 bytes .../__pycache__/_sysconfig.cpython-311.pyc | Bin 0 -> 8937 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 4058 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 -> 6466 bytes .../__pycache__/_json.cpython-311.pyc | Bin 0 -> 3620 bytes .../metadata/__pycache__/base.cpython-311.pyc | Bin 0 -> 38065 bytes .../__pycache__/pkg_resources.cpython-311.pyc | Bin 0 -> 16913 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 -> 412 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 3619 bytes .../__pycache__/_dists.cpython-311.pyc | Bin 0 -> 14635 bytes .../__pycache__/_envs.cpython-311.pyc | Bin 0 -> 12473 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 -> 329 bytes .../__pycache__/candidate.cpython-311.pyc | Bin 0 -> 2148 bytes .../__pycache__/direct_url.cpython-311.pyc | Bin 0 -> 12311 bytes .../format_control.cpython-311.pyc | Bin 0 -> 4712 bytes .../models/__pycache__/index.cpython-311.pyc | Bin 0 -> 1954 bytes .../installation_report.cpython-311.pyc | Bin 0 -> 2668 bytes .../models/__pycache__/link.cpython-311.pyc | Bin 0 -> 26500 bytes .../models/__pycache__/scheme.cpython-311.pyc | Bin 0 -> 1320 bytes .../__pycache__/search_scope.cpython-311.pyc | Bin 0 -> 5883 bytes .../selection_prefs.cpython-311.pyc | Bin 0 -> 2051 bytes .../__pycache__/target_python.cpython-311.pyc | Bin 0 -> 4813 bytes .../models/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 6476 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 -> 317 bytes .../network/__pycache__/auth.cpython-311.pyc | Bin 0 -> 19121 bytes .../network/__pycache__/cache.cpython-311.pyc | Bin 0 -> 5240 bytes .../__pycache__/download.cpython-311.pyc | Bin 0 -> 9632 bytes .../__pycache__/lazy_wheel.cpython-311.pyc | Bin 0 -> 13078 bytes .../__pycache__/session.cpython-311.pyc | Bin 0 -> 21345 bytes .../network/__pycache__/utils.cpython-311.pyc | Bin 0 -> 2466 bytes .../__pycache__/xmlrpc.cpython-311.pyc | Bin 0 -> 3245 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 -> 255 bytes .../__pycache__/check.cpython-311.pyc | Bin 0 -> 6688 bytes .../__pycache__/freeze.cpython-311.pyc | Bin 0 -> 11651 bytes .../__pycache__/prepare.cpython-311.pyc | Bin 0 -> 26435 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 261 bytes .../__pycache__/build_tracker.cpython-311.pyc | Bin 0 -> 8184 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 0 -> 2332 bytes .../metadata_editable.cpython-311.pyc | Bin 0 -> 2368 bytes .../metadata_legacy.cpython-311.pyc | Bin 0 -> 3768 bytes .../build/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 1998 bytes .../wheel_editable.cpython-311.pyc | Bin 0 -> 2442 bytes .../__pycache__/wheel_legacy.cpython-311.pyc | Bin 0 -> 4549 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 -> 329 bytes .../editable_legacy.cpython-311.pyc | Bin 0 -> 2325 bytes .../__pycache__/legacy.cpython-311.pyc | Bin 0 -> 6165 bytes .../install/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 40051 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 -> 4501 bytes .../__pycache__/constructors.cpython-311.pyc | Bin 0 -> 20760 bytes .../req/__pycache__/req_file.cpython-311.pyc | Bin 0 -> 22489 bytes .../__pycache__/req_install.cpython-311.pyc | Bin 0 -> 40401 bytes .../req/__pycache__/req_set.cpython-311.pyc | Bin 0 -> 6057 bytes .../__pycache__/req_uninstall.cpython-311.pyc | Bin 0 -> 37055 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 -> 255 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 1426 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 262 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 0 -> 23848 bytes .../_internal/resolution/legacy/resolver.py | 600 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 266 bytes .../__pycache__/base.cpython-311.pyc | Bin 0 -> 9679 bytes .../__pycache__/candidates.cpython-311.pyc | Bin 0 -> 28889 bytes .../__pycache__/factory.cpython-311.pyc | Bin 0 -> 32033 bytes .../found_candidates.cpython-311.pyc | Bin 0 -> 6814 bytes .../__pycache__/provider.cpython-311.pyc | Bin 0 -> 11108 bytes .../__pycache__/reporter.cpython-311.pyc | Bin 0 -> 4711 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 11176 bytes .../__pycache__/resolver.cpython-311.pyc | Bin 0 -> 12363 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 -> 250 bytes .../utils/__pycache__/_log.cpython-311.pyc | Bin 0 -> 2071 bytes .../utils/__pycache__/appdirs.cpython-311.pyc | Bin 0 -> 2609 bytes .../utils/__pycache__/compat.cpython-311.pyc | Bin 0 -> 2317 bytes .../compatibility_tags.cpython-311.pyc | Bin 0 -> 6809 bytes .../__pycache__/datetime.cpython-311.pyc | Bin 0 -> 767 bytes .../__pycache__/deprecation.cpython-311.pyc | Bin 0 -> 7140 bytes .../direct_url_helpers.cpython-311.pyc | Bin 0 -> 3773 bytes .../distutils_args.cpython-311.pyc | Bin 0 -> 1517 bytes .../__pycache__/egg_link.cpython-311.pyc | Bin 0 -> 3288 bytes .../__pycache__/encoding.cpython-311.pyc | Bin 0 -> 2373 bytes .../__pycache__/entrypoints.cpython-311.pyc | Bin 0 -> 4295 bytes .../__pycache__/filesystem.cpython-311.pyc | Bin 0 -> 8280 bytes .../__pycache__/filetypes.cpython-311.pyc | Bin 0 -> 1366 bytes .../utils/__pycache__/glibc.cpython-311.pyc | Bin 0 -> 2609 bytes .../utils/__pycache__/hashes.cpython-311.pyc | Bin 0 -> 8387 bytes .../inject_securetransport.cpython-311.pyc | Bin 0 -> 1384 bytes .../utils/__pycache__/logging.cpython-311.pyc | Bin 0 -> 15509 bytes .../utils/__pycache__/misc.cpython-311.pyc | Bin 0 -> 37751 bytes .../utils/__pycache__/models.cpython-311.pyc | Bin 0 -> 2990 bytes .../__pycache__/packaging.cpython-311.pyc | Bin 0 -> 2857 bytes .../setuptools_build.cpython-311.pyc | Bin 0 -> 6154 bytes .../__pycache__/subprocess.cpython-311.pyc | Bin 0 -> 9944 bytes .../__pycache__/temp_dir.cpython-311.pyc | Bin 0 -> 11471 bytes .../__pycache__/unpacking.cpython-311.pyc | Bin 0 -> 12946 bytes .../utils/__pycache__/urls.cpython-311.pyc | Bin 0 -> 2743 bytes .../__pycache__/virtualenv.cpython-311.pyc | Bin 0 -> 4990 bytes .../utils/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 7160 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 -> 685 bytes .../vcs/__pycache__/bazaar.cpython-311.pyc | Bin 0 -> 5910 bytes .../vcs/__pycache__/git.cpython-311.pyc | Bin 0 -> 21574 bytes .../vcs/__pycache__/mercurial.cpython-311.pyc | Bin 0 -> 8756 bytes .../__pycache__/subversion.cpython-311.pyc | Bin 0 -> 14653 bytes .../versioncontrol.cpython-311.pyc | Bin 0 -> 31922 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 -> 5663 bytes .../_vendor/__pycache__/six.cpython-311.pyc | Bin 0 -> 46465 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 97495 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 892 bytes .../__pycache__/_cmd.cpython-311.pyc | Bin 0 -> 2747 bytes .../__pycache__/adapter.cpython-311.pyc | Bin 0 -> 5554 bytes .../__pycache__/cache.cpython-311.pyc | Bin 0 -> 3828 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 1185 bytes .../__pycache__/controller.cpython-311.pyc | Bin 0 -> 16500 bytes .../__pycache__/filewrapper.cpython-311.pyc | Bin 0 -> 4287 bytes .../__pycache__/heuristics.cpython-311.pyc | Bin 0 -> 6732 bytes .../__pycache__/serialize.cpython-311.pyc | Bin 0 -> 8447 bytes .../__pycache__/wrapper.cpython-311.pyc | Bin 0 -> 1013 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 -> 467 bytes .../__pycache__/file_cache.cpython-311.pyc | Bin 0 -> 8450 bytes .../__pycache__/redis_cache.cpython-311.pyc | Bin 0 -> 2547 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 -> 392 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 793 bytes .../certifi/__pycache__/core.cpython-311.pyc | Bin 0 -> 4035 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 -> 5124 bytes .../__pycache__/big5freq.cpython-311.pyc | Bin 0 -> 27254 bytes .../__pycache__/big5prober.cpython-311.pyc | Bin 0 -> 1729 bytes .../chardistribution.cpython-311.pyc | Bin 0 -> 11321 bytes .../charsetgroupprober.cpython-311.pyc | Bin 0 -> 4351 bytes .../__pycache__/charsetprober.cpython-311.pyc | Bin 0 -> 5597 bytes .../codingstatemachine.cpython-311.pyc | Bin 0 -> 4048 bytes .../codingstatemachinedict.cpython-311.pyc | Bin 0 -> 1004 bytes .../__pycache__/cp949prober.cpython-311.pyc | Bin 0 -> 1738 bytes .../chardet/__pycache__/enums.cpython-311.pyc | Bin 0 -> 3439 bytes .../__pycache__/escprober.cpython-311.pyc | Bin 0 -> 4955 bytes .../chardet/__pycache__/escsm.cpython-311.pyc | Bin 0 -> 12694 bytes .../__pycache__/eucjpprober.cpython-311.pyc | Bin 0 -> 4781 bytes .../__pycache__/euckrfreq.cpython-311.pyc | Bin 0 -> 12137 bytes .../__pycache__/euckrprober.cpython-311.pyc | Bin 0 -> 1730 bytes .../__pycache__/euctwfreq.cpython-311.pyc | Bin 0 -> 27259 bytes .../__pycache__/euctwprober.cpython-311.pyc | Bin 0 -> 1730 bytes .../__pycache__/gb2312freq.cpython-311.pyc | Bin 0 -> 19181 bytes .../__pycache__/gb2312prober.cpython-311.pyc | Bin 0 -> 1745 bytes .../__pycache__/hebrewprober.cpython-311.pyc | Bin 0 -> 5734 bytes .../__pycache__/jisfreq.cpython-311.pyc | Bin 0 -> 22210 bytes .../__pycache__/johabfreq.cpython-311.pyc | Bin 0 -> 84714 bytes .../__pycache__/johabprober.cpython-311.pyc | Bin 0 -> 1736 bytes .../__pycache__/jpcntx.cpython-311.pyc | Bin 0 -> 40218 bytes .../langbulgarianmodel.cpython-311.pyc | Bin 0 -> 85888 bytes .../langgreekmodel.cpython-311.pyc | Bin 0 -> 79310 bytes .../langhebrewmodel.cpython-311.pyc | Bin 0 -> 80072 bytes .../langhungarianmodel.cpython-311.pyc | Bin 0 -> 85842 bytes .../langrussianmodel.cpython-311.pyc | Bin 0 -> 108789 bytes .../__pycache__/langthaimodel.cpython-311.pyc | Bin 0 -> 80250 bytes .../langturkishmodel.cpython-311.pyc | Bin 0 -> 80089 bytes .../__pycache__/latin1prober.cpython-311.pyc | Bin 0 -> 7385 bytes .../macromanprober.cpython-311.pyc | Bin 0 -> 7552 bytes .../mbcharsetprober.cpython-311.pyc | Bin 0 -> 4173 bytes .../mbcsgroupprober.cpython-311.pyc | Bin 0 -> 2043 bytes .../__pycache__/mbcssm.cpython-311.pyc | Bin 0 -> 31783 bytes .../__pycache__/resultdict.cpython-311.pyc | Bin 0 -> 822 bytes .../sbcharsetprober.cpython-311.pyc | Bin 0 -> 6448 bytes .../sbcsgroupprober.cpython-311.pyc | Bin 0 -> 2993 bytes .../__pycache__/sjisprober.cpython-311.pyc | Bin 0 -> 4886 bytes .../universaldetector.cpython-311.pyc | Bin 0 -> 12514 bytes .../__pycache__/utf1632prober.cpython-311.pyc | Bin 0 -> 10634 bytes .../__pycache__/utf8prober.cpython-311.pyc | Bin 0 -> 3521 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 557 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 -> 254 bytes .../__pycache__/chardetect.cpython-311.pyc | Bin 0 -> 4393 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 -> 259 bytes .../__pycache__/languages.cpython-311.pyc | Bin 0 -> 10859 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 -> 626 bytes .../colorama/__pycache__/ansi.cpython-311.pyc | Bin 0 -> 4624 bytes .../__pycache__/ansitowin32.cpython-311.pyc | Bin 0 -> 16270 bytes .../__pycache__/initialise.cpython-311.pyc | Bin 0 -> 3987 bytes .../__pycache__/win32.cpython-311.pyc | Bin 0 -> 7975 bytes .../__pycache__/winterm.cpython-311.pyc | Bin 0 -> 9201 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 -> 257 bytes .../__pycache__/ansi_test.cpython-311.pyc | Bin 0 -> 5902 bytes .../ansitowin32_test.cpython-311.pyc | Bin 0 -> 21569 bytes .../initialise_test.cpython-311.pyc | Bin 0 -> 14196 bytes .../__pycache__/isatty_test.cpython-311.pyc | Bin 0 -> 6761 bytes .../tests/__pycache__/utils.cpython-311.pyc | Bin 0 -> 2936 bytes .../__pycache__/winterm_test.cpython-311.pyc | Bin 0 -> 7289 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 -> 1495 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 52361 bytes .../__pycache__/database.cpython-311.pyc | Bin 0 -> 72149 bytes .../distlib/__pycache__/index.cpython-311.pyc | Bin 0 -> 26738 bytes .../__pycache__/locators.cpython-311.pyc | Bin 0 -> 65914 bytes .../__pycache__/manifest.cpython-311.pyc | Bin 0 -> 17081 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 8217 bytes .../__pycache__/metadata.cpython-311.pyc | Bin 0 -> 47165 bytes .../__pycache__/resources.cpython-311.pyc | Bin 0 -> 19044 bytes .../__pycache__/scripts.cpython-311.pyc | Bin 0 -> 21320 bytes .../distlib/__pycache__/util.cpython-311.pyc | Bin 0 -> 97499 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 34626 bytes .../distlib/__pycache__/wheel.cpython-311.pyc | Bin 0 -> 60430 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 -> 1248 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 382 bytes .../distro/__pycache__/distro.cpython-311.pyc | Bin 0 -> 57781 bytes .../pip/_vendor/distro/distro.py | 1399 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 1149 bytes .../idna/__pycache__/codec.cpython-311.pyc | Bin 0 -> 5440 bytes .../idna/__pycache__/compat.cpython-311.pyc | Bin 0 -> 1066 bytes .../idna/__pycache__/core.cpython-311.pyc | Bin 0 -> 19501 bytes .../idna/__pycache__/idnadata.cpython-311.pyc | Bin 0 -> 39025 bytes .../__pycache__/intranges.cpython-311.pyc | Bin 0 -> 3034 bytes .../__pycache__/package_data.cpython-311.pyc | Bin 0 -> 269 bytes .../__pycache__/uts46data.cpython-311.pyc | Bin 0 -> 163249 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 -> 2128 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 2429 bytes .../msgpack/__pycache__/ext.cpython-311.pyc | Bin 0 -> 9215 bytes .../__pycache__/fallback.cpython-311.pyc | Bin 0 -> 47242 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 -> 693 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 614 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13280 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 8048 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3736 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16576 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7691 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34414 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21399 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6734 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21926 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 -> 158282 bytes .../__pycache__/py31compat.cpython-311.pyc | Bin 0 -> 1035 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 -> 12981 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 2178 bytes .../__pycache__/android.cpython-311.pyc | Bin 0 -> 6408 bytes .../__pycache__/api.cpython-311.pyc | Bin 0 -> 7235 bytes .../__pycache__/macos.cpython-311.pyc | Bin 0 -> 4645 bytes .../__pycache__/unix.cpython-311.pyc | Bin 0 -> 11077 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 364 bytes .../__pycache__/windows.cpython-311.pyc | Bin 0 -> 10013 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 -> 3896 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 832 bytes .../__pycache__/cmdline.cpython-311.pyc | Bin 0 -> 30343 bytes .../__pycache__/console.cpython-311.pyc | Bin 0 -> 3095 bytes .../__pycache__/filter.cpython-311.pyc | Bin 0 -> 3556 bytes .../__pycache__/formatter.cpython-311.pyc | Bin 0 -> 3922 bytes .../__pycache__/lexer.cpython-311.pyc | Bin 0 -> 40450 bytes .../__pycache__/modeline.cpython-311.pyc | Bin 0 -> 1775 bytes .../__pycache__/plugin.cpython-311.pyc | Bin 0 -> 3788 bytes .../__pycache__/regexopt.cpython-311.pyc | Bin 0 -> 5082 bytes .../__pycache__/scanner.cpython-311.pyc | Bin 0 -> 4937 bytes .../__pycache__/sphinxext.cpython-311.pyc | Bin 0 -> 8368 bytes .../__pycache__/style.cpython-311.pyc | Bin 0 -> 7476 bytes .../__pycache__/token.cpython-311.pyc | Bin 0 -> 7516 bytes .../__pycache__/unistring.cpython-311.pyc | Bin 0 -> 33850 bytes .../pygments/__pycache__/util.cpython-311.pyc | Bin 0 -> 14643 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 -> 40156 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 143 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6922 bytes .../__pycache__/_mapping.cpython-311.pyc | Bin 0 -> 4204 bytes .../__pycache__/bbcode.cpython-311.pyc | Bin 0 -> 4530 bytes .../__pycache__/groff.cpython-311.pyc | Bin 0 -> 7863 bytes .../__pycache__/html.cpython-311.pyc | Bin 0 -> 42648 bytes .../__pycache__/img.cpython-311.pyc | Bin 0 -> 28620 bytes .../__pycache__/irc.cpython-311.pyc | Bin 0 -> 7723 bytes .../__pycache__/latex.cpython-311.pyc | Bin 0 -> 21856 bytes .../__pycache__/other.cpython-311.pyc | Bin 0 -> 7684 bytes .../__pycache__/pangomarkup.cpython-311.pyc | Bin 0 -> 3228 bytes .../__pycache__/rtf.cpython-311.pyc | Bin 0 -> 6895 bytes .../__pycache__/svg.cpython-311.pyc | Bin 0 -> 9715 bytes .../__pycache__/terminal.cpython-311.pyc | Bin 0 -> 6094 bytes .../__pycache__/terminal256.cpython-311.pyc | Bin 0 -> 16460 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 -> 15199 bytes .../__pycache__/_mapping.cpython-311.pyc | Bin 0 -> 62830 bytes .../lexers/__pycache__/python.cpython-311.pyc | Bin 0 -> 44031 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 -> 4509 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 -> 8399 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8513 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14835 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277721 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12977 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53678 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36361 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19557 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15415 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14314 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 -> 28080 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 -> 757 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 455 bytes .../__pycache__/_impl.cpython-311.pyc | Bin 0 -> 16721 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 -> 1217 bytes .../__pycache__/_in_process.cpython-311.pyc | Bin 0 -> 16539 bytes .../_in_process/_in_process.py | 353 + .../pip/_vendor/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 6501 bytes .../__pycache__/__version__.cpython-311.pyc | Bin 0 -> 638 bytes .../_internal_utils.cpython-311.pyc | Bin 0 -> 2135 bytes .../__pycache__/adapters.cpython-311.pyc | Bin 0 -> 24938 bytes .../requests/__pycache__/api.cpython-311.pyc | Bin 0 -> 7483 bytes .../requests/__pycache__/auth.cpython-311.pyc | Bin 0 -> 14682 bytes .../__pycache__/certs.cpython-311.pyc | Bin 0 -> 1034 bytes .../__pycache__/compat.cpython-311.pyc | Bin 0 -> 1860 bytes .../__pycache__/cookies.cpython-311.pyc | Bin 0 -> 27162 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8577 bytes .../requests/__pycache__/help.cpython-311.pyc | Bin 0 -> 4572 bytes .../__pycache__/hooks.cpython-311.pyc | Bin 0 -> 1302 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 38833 bytes .../__pycache__/packages.cpython-311.pyc | Bin 0 -> 882 bytes .../__pycache__/sessions.cpython-311.pyc | Bin 0 -> 29671 bytes .../__pycache__/status_codes.cpython-311.pyc | Bin 0 -> 6289 bytes .../__pycache__/structures.cpython-311.pyc | Bin 0 -> 6274 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 40188 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 -> 805 bytes .../__pycache__/providers.cpython-311.pyc | Bin 0 -> 7124 bytes .../__pycache__/reporters.cpython-311.pyc | Bin 0 -> 2854 bytes .../__pycache__/resolvers.cpython-311.pyc | Bin 0 -> 25300 bytes .../__pycache__/structs.cpython-311.pyc | Bin 0 -> 11382 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 260 bytes .../collections_abc.cpython-311.pyc | Bin 0 -> 535 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 -> 7548 bytes .../rich/__pycache__/__main__.cpython-311.pyc | Bin 0 -> 11626 bytes .../__pycache__/_cell_widths.cpython-311.pyc | Bin 0 -> 7887 bytes .../__pycache__/_emoji_codes.cpython-311.pyc | Bin 0 -> 208574 bytes .../_emoji_replace.cpython-311.pyc | Bin 0 -> 1986 bytes .../_export_format.cpython-311.pyc | Bin 0 -> 2391 bytes .../__pycache__/_extension.cpython-311.pyc | Bin 0 -> 687 bytes .../rich/__pycache__/_inspect.cpython-311.pyc | Bin 0 -> 14239 bytes .../__pycache__/_log_render.cpython-311.pyc | Bin 0 -> 4821 bytes .../rich/__pycache__/_loop.cpython-311.pyc | Bin 0 -> 2167 bytes .../__pycache__/_null_file.cpython-311.pyc | Bin 0 -> 4732 bytes .../__pycache__/_palettes.cpython-311.pyc | Bin 0 -> 5303 bytes .../rich/__pycache__/_pick.cpython-311.pyc | Bin 0 -> 848 bytes .../rich/__pycache__/_ratio.cpython-311.pyc | Bin 0 -> 7986 bytes .../__pycache__/_spinners.cpython-311.pyc | Bin 0 -> 13736 bytes .../rich/__pycache__/_stack.cpython-311.pyc | Bin 0 -> 1182 bytes .../rich/__pycache__/_timer.cpython-311.pyc | Bin 0 -> 1035 bytes .../_win32_console.cpython-311.pyc | Bin 0 -> 30223 bytes .../rich/__pycache__/_windows.cpython-311.pyc | Bin 0 -> 2882 bytes .../_windows_renderer.cpython-311.pyc | Bin 0 -> 4073 bytes .../rich/__pycache__/_wrap.cpython-311.pyc | Bin 0 -> 2838 bytes .../rich/__pycache__/abc.cpython-311.pyc | Bin 0 -> 1979 bytes .../rich/__pycache__/align.cpython-311.pyc | Bin 0 -> 13528 bytes .../rich/__pycache__/ansi.cpython-311.pyc | Bin 0 -> 10504 bytes .../rich/__pycache__/bar.cpython-311.pyc | Bin 0 -> 4601 bytes .../rich/__pycache__/box.cpython-311.pyc | Bin 0 -> 13043 bytes .../rich/__pycache__/cells.cpython-311.pyc | Bin 0 -> 6493 bytes .../rich/__pycache__/color.cpython-311.pyc | Bin 0 -> 27624 bytes .../__pycache__/color_triplet.cpython-311.pyc | Bin 0 -> 1927 bytes .../rich/__pycache__/columns.cpython-311.pyc | Bin 0 -> 10698 bytes .../rich/__pycache__/console.cpython-311.pyc | Bin 0 -> 123214 bytes .../__pycache__/constrain.cpython-311.pyc | Bin 0 -> 2519 bytes .../__pycache__/containers.cpython-311.pyc | Bin 0 -> 10860 bytes .../rich/__pycache__/control.cpython-311.pyc | Bin 0 -> 11951 bytes .../default_styles.cpython-311.pyc | Bin 0 -> 12551 bytes .../rich/__pycache__/diagnose.cpython-311.pyc | Bin 0 -> 1874 bytes .../rich/__pycache__/emoji.cpython-311.pyc | Bin 0 -> 4852 bytes .../rich/__pycache__/errors.cpython-311.pyc | Bin 0 -> 2383 bytes .../__pycache__/file_proxy.cpython-311.pyc | Bin 0 -> 3831 bytes .../rich/__pycache__/filesize.cpython-311.pyc | Bin 0 -> 3355 bytes .../__pycache__/highlighter.cpython-311.pyc | Bin 0 -> 11042 bytes .../rich/__pycache__/json.cpython-311.pyc | Bin 0 -> 6735 bytes .../rich/__pycache__/jupyter.cpython-311.pyc | Bin 0 -> 6458 bytes .../rich/__pycache__/layout.cpython-311.pyc | Bin 0 -> 23365 bytes .../rich/__pycache__/live.cpython-311.pyc | Bin 0 -> 21186 bytes .../__pycache__/live_render.cpython-311.pyc | Bin 0 -> 5199 bytes .../rich/__pycache__/logging.cpython-311.pyc | Bin 0 -> 14570 bytes .../rich/__pycache__/markup.cpython-311.pyc | Bin 0 -> 10492 bytes .../rich/__pycache__/measure.cpython-311.pyc | Bin 0 -> 7325 bytes .../rich/__pycache__/padding.cpython-311.pyc | Bin 0 -> 7541 bytes .../rich/__pycache__/pager.cpython-311.pyc | Bin 0 -> 2299 bytes .../rich/__pycache__/palette.cpython-311.pyc | Bin 0 -> 6032 bytes .../rich/__pycache__/panel.cpython-311.pyc | Bin 0 -> 12788 bytes .../rich/__pycache__/pretty.cpython-311.pyc | Bin 0 -> 44881 bytes .../rich/__pycache__/progress.cpython-311.pyc | Bin 0 -> 82760 bytes .../__pycache__/progress_bar.cpython-311.pyc | Bin 0 -> 11066 bytes .../rich/__pycache__/prompt.cpython-311.pyc | Bin 0 -> 16432 bytes .../rich/__pycache__/protocol.cpython-311.pyc | Bin 0 -> 2150 bytes .../rich/__pycache__/region.cpython-311.pyc | Bin 0 -> 713 bytes .../rich/__pycache__/repr.cpython-311.pyc | Bin 0 -> 7712 bytes .../rich/__pycache__/rule.cpython-311.pyc | Bin 0 -> 7751 bytes .../rich/__pycache__/scope.cpython-311.pyc | Bin 0 -> 4405 bytes .../rich/__pycache__/screen.cpython-311.pyc | Bin 0 -> 2828 bytes .../rich/__pycache__/segment.cpython-311.pyc | Bin 0 -> 31595 bytes .../rich/__pycache__/spinner.cpython-311.pyc | Bin 0 -> 6944 bytes .../rich/__pycache__/status.cpython-311.pyc | Bin 0 -> 6812 bytes .../rich/__pycache__/style.cpython-311.pyc | Bin 0 -> 34385 bytes .../rich/__pycache__/styled.cpython-311.pyc | Bin 0 -> 2493 bytes .../rich/__pycache__/syntax.cpython-311.pyc | Bin 0 -> 42587 bytes .../rich/__pycache__/table.cpython-311.pyc | Bin 0 -> 48854 bytes .../terminal_theme.cpython-311.pyc | Bin 0 -> 3759 bytes .../rich/__pycache__/text.cpython-311.pyc | Bin 0 -> 65270 bytes .../rich/__pycache__/theme.cpython-311.pyc | Bin 0 -> 7197 bytes .../rich/__pycache__/themes.cpython-311.pyc | Bin 0 -> 409 bytes .../__pycache__/traceback.cpython-311.pyc | Bin 0 -> 31723 bytes .../rich/__pycache__/tree.cpython-311.pyc | Bin 0 -> 12580 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 -> 27847 bytes .../__pycache__/_asyncio.cpython-311.pyc | Bin 0 -> 4854 bytes .../__pycache__/_utils.cpython-311.pyc | Bin 0 -> 2119 bytes .../__pycache__/after.cpython-311.pyc | Bin 0 -> 1746 bytes .../__pycache__/before.cpython-311.pyc | Bin 0 -> 1580 bytes .../__pycache__/before_sleep.cpython-311.pyc | Bin 0 -> 2157 bytes .../tenacity/__pycache__/nap.cpython-311.pyc | Bin 0 -> 1619 bytes .../__pycache__/retry.cpython-311.pyc | Bin 0 -> 15093 bytes .../tenacity/__pycache__/stop.cpython-311.pyc | Bin 0 -> 5947 bytes .../__pycache__/tornadoweb.cpython-311.pyc | Bin 0 -> 2965 bytes .../tenacity/__pycache__/wait.cpython-311.pyc | Bin 0 -> 13419 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 -> 464 bytes .../tomli/__pycache__/_parser.cpython-311.pyc | Bin 0 -> 30903 bytes .../tomli/__pycache__/_re.cpython-311.pyc | Bin 0 -> 4543 bytes .../tomli/__pycache__/_types.cpython-311.pyc | Bin 0 -> 456 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 -> 3762 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 18350 bytes .../__pycache__/_version.cpython-311.pyc | Bin 0 -> 272 bytes .../__pycache__/connection.cpython-311.pyc | Bin 0 -> 21946 bytes .../connectionpool.cpython-311.pyc | Bin 0 -> 37689 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 16176 bytes .../__pycache__/fields.cpython-311.pyc | Bin 0 -> 11469 bytes .../__pycache__/filepost.cpython-311.pyc | Bin 0 -> 4550 bytes .../__pycache__/poolmanager.cpython-311.pyc | Bin 0 -> 21873 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 6713 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 36596 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 -> 258 bytes .../_appengine_environ.cpython-311.pyc | Bin 0 -> 1997 bytes .../__pycache__/appengine.cpython-311.pyc | Bin 0 -> 12204 bytes .../__pycache__/ntlmpool.cpython-311.pyc | Bin 0 -> 6281 bytes .../__pycache__/pyopenssl.cpython-311.pyc | Bin 0 -> 25790 bytes .../securetransport.cpython-311.pyc | Bin 0 -> 36897 bytes .../contrib/__pycache__/socks.cpython-311.pyc | Bin 0 -> 8142 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 275 bytes .../__pycache__/bindings.cpython-311.pyc | Bin 0 -> 17022 bytes .../__pycache__/low_level.cpython-311.pyc | Bin 0 -> 15659 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 -> 259 bytes .../packages/__pycache__/six.cpython-311.pyc | Bin 0 -> 46501 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 269 bytes .../__pycache__/makefile.cpython-311.pyc | Bin 0 -> 2016 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 -> 1461 bytes .../__pycache__/connection.cpython-311.pyc | Bin 0 -> 5188 bytes .../util/__pycache__/proxy.cpython-311.pyc | Bin 0 -> 1770 bytes .../util/__pycache__/queue.cpython-311.pyc | Bin 0 -> 1553 bytes .../util/__pycache__/request.cpython-311.pyc | Bin 0 -> 4673 bytes .../util/__pycache__/response.cpython-311.pyc | Bin 0 -> 3542 bytes .../util/__pycache__/retry.cpython-311.pyc | Bin 0 -> 22810 bytes .../util/__pycache__/ssl_.cpython-311.pyc | Bin 0 -> 16873 bytes .../ssl_match_hostname.cpython-311.pyc | Bin 0 -> 5852 bytes .../__pycache__/ssltransport.cpython-311.pyc | Bin 0 -> 11681 bytes .../util/__pycache__/timeout.cpython-311.pyc | Bin 0 -> 11089 bytes .../util/__pycache__/url.cpython-311.pyc | Bin 0 -> 17613 bytes .../util/__pycache__/wait.cpython-311.pyc | Bin 0 -> 5055 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 -> 12935 bytes .../__pycache__/labels.cpython-311.pyc | Bin 0 -> 7335 bytes .../__pycache__/mklabels.cpython-311.pyc | Bin 0 -> 3263 bytes .../__pycache__/tests.cpython-311.pyc | Bin 0 -> 11241 bytes .../x_user_defined.cpython-311.pyc | Bin 0 -> 3615 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 -> 156166 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 252 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 97469 bytes .../_vendor/__pycache__/zipp.cpython-311.pyc | Bin 0 -> 16045 bytes .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 886 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 10803 bytes .../__pycache__/_common.cpython-311.pyc | Bin 0 -> 4330 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 5615 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1448 bytes .../__pycache__/_legacy.cpython-311.pyc | Bin 0 -> 6546 bytes .../__pycache__/abc.cpython-311.pyc | Bin 0 -> 7547 bytes .../__pycache__/readers.cpython-311.pyc | Bin 0 -> 8421 bytes .../__pycache__/simple.cpython-311.pyc | Bin 0 -> 6443 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 -> 259 bytes .../__pycache__/context.cpython-311.pyc | Bin 0 -> 11034 bytes .../__pycache__/functools.cpython-311.pyc | Bin 0 -> 20345 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 -> 26662 bytes .../_vendor/more_itertools/__init__.py | 6 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 431 bytes .../__pycache__/more.cpython-311.pyc | Bin 0 -> 169553 bytes .../__pycache__/recipes.cpython-311.pyc | Bin 0 -> 33573 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 -> 703 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 624 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13290 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 8058 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3746 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16595 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7710 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34424 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21409 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6744 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21936 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 -> 12884 bytes .../__pycache__/__main__.cpython-311.pyc | Bin 0 -> 2176 bytes .../__pycache__/android.cpython-311.pyc | Bin 0 -> 6418 bytes .../__pycache__/api.cpython-311.pyc | Bin 0 -> 7245 bytes .../__pycache__/macos.cpython-311.pyc | Bin 0 -> 4655 bytes .../__pycache__/unix.cpython-311.pyc | Bin 0 -> 11087 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 374 bytes .../__pycache__/windows.cpython-311.pyc | Bin 0 -> 10023 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 -> 8397 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8523 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14845 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277697 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12987 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53688 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36371 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19567 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15425 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14324 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 -> 28060 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 -> 4375 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 -> 13980 bytes .../_deprecation_warning.cpython-311.pyc | Bin 0 -> 696 bytes .../__pycache__/_entry_points.cpython-311.pyc | Bin 0 -> 5253 bytes .../__pycache__/_imp.cpython-311.pyc | Bin 0 -> 3709 bytes .../__pycache__/_importlib.cpython-311.pyc | Bin 0 -> 2009 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1208 bytes .../__pycache__/_path.cpython-311.pyc | Bin 0 -> 1529 bytes .../__pycache__/_reqs.cpython-311.pyc | Bin 0 -> 1190 bytes .../__pycache__/archive_util.cpython-311.pyc | Bin 0 -> 10218 bytes .../__pycache__/build_meta.cpython-311.pyc | Bin 0 -> 28201 bytes .../__pycache__/dep_util.cpython-311.pyc | Bin 0 -> 1344 bytes .../__pycache__/depends.cpython-311.pyc | Bin 0 -> 8029 bytes .../__pycache__/discovery.cpython-311.pyc | Bin 0 -> 31182 bytes .../__pycache__/dist.cpython-311.pyc | Bin 0 -> 63849 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 3005 bytes .../__pycache__/extension.cpython-311.pyc | Bin 0 -> 6861 bytes .../__pycache__/glob.cpython-311.pyc | Bin 0 -> 6618 bytes .../__pycache__/installer.cpython-311.pyc | Bin 0 -> 5668 bytes .../__pycache__/launch.cpython-311.pyc | Bin 0 -> 1584 bytes .../__pycache__/logging.cpython-311.pyc | Bin 0 -> 2151 bytes .../__pycache__/monkey.cpython-311.pyc | Bin 0 -> 7061 bytes .../__pycache__/msvc.cpython-311.pyc | Bin 0 -> 64234 bytes .../__pycache__/namespaces.cpython-311.pyc | Bin 0 -> 5716 bytes .../__pycache__/package_index.cpython-311.pyc | Bin 0 -> 61989 bytes .../__pycache__/py34compat.cpython-311.pyc | Bin 0 -> 771 bytes .../__pycache__/sandbox.cpython-311.pyc | Bin 0 -> 27387 bytes .../__pycache__/unicode_utils.cpython-311.pyc | Bin 0 -> 1873 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 491 bytes .../__pycache__/wheel.cpython-311.pyc | Bin 0 -> 15547 bytes .../windows_support.cpython-311.pyc | Bin 0 -> 1488 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 14 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 615 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 8585 bytes .../__pycache__/_functools.cpython-311.pyc | Bin 0 -> 917 bytes .../__pycache__/_log.cpython-311.pyc | Bin 0 -> 334 bytes .../__pycache__/_macos_compat.cpython-311.pyc | Bin 0 -> 626 bytes .../__pycache__/_msvccompiler.cpython-311.pyc | Bin 0 -> 25128 bytes .../__pycache__/archive_util.cpython-311.pyc | Bin 0 -> 10676 bytes .../__pycache__/bcppcompiler.cpython-311.pyc | Bin 0 -> 13502 bytes .../__pycache__/ccompiler.cpython-311.pyc | Bin 0 -> 46371 bytes .../__pycache__/cmd.cpython-311.pyc | Bin 0 -> 18895 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 6096 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 9986 bytes .../cygwinccompiler.cpython-311.pyc | Bin 0 -> 13680 bytes .../__pycache__/debug.cpython-311.pyc | Bin 0 -> 378 bytes .../__pycache__/dep_util.cpython-311.pyc | Bin 0 -> 4040 bytes .../__pycache__/dir_util.cpython-311.pyc | Bin 0 -> 10421 bytes .../__pycache__/dist.cpython-311.pyc | Bin 0 -> 55544 bytes .../__pycache__/errors.cpython-311.pyc | Bin 0 -> 6851 bytes .../__pycache__/extension.cpython-311.pyc | Bin 0 -> 10232 bytes .../__pycache__/fancy_getopt.cpython-311.pyc | Bin 0 -> 17291 bytes .../__pycache__/file_util.cpython-311.pyc | Bin 0 -> 10725 bytes .../__pycache__/filelist.cpython-311.pyc | Bin 0 -> 17665 bytes .../__pycache__/log.cpython-311.pyc | Bin 0 -> 2749 bytes .../__pycache__/msvc9compiler.cpython-311.pyc | Bin 0 -> 33614 bytes .../__pycache__/msvccompiler.cpython-311.pyc | Bin 0 -> 27026 bytes .../__pycache__/py38compat.cpython-311.pyc | Bin 0 -> 678 bytes .../__pycache__/py39compat.cpython-311.pyc | Bin 0 -> 1046 bytes .../__pycache__/spawn.cpython-311.pyc | Bin 0 -> 4490 bytes .../__pycache__/sysconfig.cpython-311.pyc | Bin 0 -> 22127 bytes .../__pycache__/text_file.cpython-311.pyc | Bin 0 -> 11327 bytes .../__pycache__/unixccompiler.cpython-311.pyc | Bin 0 -> 16550 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 20901 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 11403 bytes .../versionpredicate.cpython-311.pyc | Bin 0 -> 7680 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 -> 598 bytes .../_framework_compat.cpython-311.pyc | Bin 0 -> 2839 bytes .../command/__pycache__/bdist.cpython-311.pyc | Bin 0 -> 6057 bytes .../__pycache__/bdist_dumb.cpython-311.pyc | Bin 0 -> 5777 bytes .../__pycache__/bdist_rpm.cpython-311.pyc | Bin 0 -> 23311 bytes .../command/__pycache__/build.cpython-311.pyc | Bin 0 -> 6112 bytes .../__pycache__/build_clib.cpython-311.pyc | Bin 0 -> 7820 bytes .../__pycache__/build_ext.cpython-311.pyc | Bin 0 -> 30330 bytes .../__pycache__/build_py.cpython-311.pyc | Bin 0 -> 17656 bytes .../__pycache__/build_scripts.cpython-311.pyc | Bin 0 -> 7910 bytes .../command/__pycache__/check.cpython-311.pyc | Bin 0 -> 7566 bytes .../command/__pycache__/clean.cpython-311.pyc | Bin 0 -> 3242 bytes .../__pycache__/config.cpython-311.pyc | Bin 0 -> 16279 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 29431 bytes .../__pycache__/install_data.cpython-311.pyc | Bin 0 -> 3819 bytes .../install_egg_info.cpython-311.pyc | Bin 0 -> 5274 bytes .../install_headers.cpython-311.pyc | Bin 0 -> 2407 bytes .../__pycache__/install_lib.cpython-311.pyc | Bin 0 -> 8728 bytes .../install_scripts.cpython-311.pyc | Bin 0 -> 3214 bytes .../__pycache__/py37compat.cpython-311.pyc | Bin 0 -> 1595 bytes .../__pycache__/register.cpython-311.pyc | Bin 0 -> 15613 bytes .../command/__pycache__/sdist.cpython-311.pyc | Bin 0 -> 23825 bytes .../__pycache__/upload.cpython-311.pyc | Bin 0 -> 10479 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 -> 249 bytes .../__pycache__/ordered_set.cpython-311.pyc | Bin 0 -> 21835 bytes .../typing_extensions.cpython-311.pyc | Bin 0 -> 107666 bytes .../_vendor/__pycache__/zipp.cpython-311.pyc | Bin 0 -> 16042 bytes .../_vendor/importlib_metadata/__init__.py | 1047 ++ .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 58288 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 3901 bytes .../__pycache__/_collections.cpython-311.pyc | Bin 0 -> 2248 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 2770 bytes .../__pycache__/_functools.cpython-311.pyc | Bin 0 -> 3688 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 2651 bytes .../__pycache__/_meta.cpython-311.pyc | Bin 0 -> 3055 bytes .../__pycache__/_text.cpython-311.pyc | Bin 0 -> 4446 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 -> 883 bytes .../__pycache__/_adapters.cpython-311.pyc | Bin 0 -> 10800 bytes .../__pycache__/_common.cpython-311.pyc | Bin 0 -> 4327 bytes .../__pycache__/_compat.cpython-311.pyc | Bin 0 -> 5612 bytes .../__pycache__/_itertools.cpython-311.pyc | Bin 0 -> 1445 bytes .../__pycache__/_legacy.cpython-311.pyc | Bin 0 -> 6543 bytes .../__pycache__/abc.cpython-311.pyc | Bin 0 -> 7544 bytes .../__pycache__/readers.cpython-311.pyc | Bin 0 -> 8418 bytes .../__pycache__/simple.cpython-311.pyc | Bin 0 -> 6440 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 -> 256 bytes .../__pycache__/context.cpython-311.pyc | Bin 0 -> 11031 bytes .../__pycache__/functools.cpython-311.pyc | Bin 0 -> 20336 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 -> 26650 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 349 bytes .../__pycache__/more.cpython-311.pyc | Bin 0 -> 149236 bytes .../__pycache__/recipes.cpython-311.pyc | Bin 0 -> 23818 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 -> 700 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 621 bytes .../__pycache__/_manylinux.cpython-311.pyc | Bin 0 -> 13287 bytes .../__pycache__/_musllinux.cpython-311.pyc | Bin 0 -> 8055 bytes .../__pycache__/_structures.cpython-311.pyc | Bin 0 -> 3743 bytes .../__pycache__/markers.cpython-311.pyc | Bin 0 -> 16589 bytes .../__pycache__/requirements.cpython-311.pyc | Bin 0 -> 7704 bytes .../__pycache__/specifiers.cpython-311.pyc | Bin 0 -> 34421 bytes .../__pycache__/tags.cpython-311.pyc | Bin 0 -> 21406 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 6741 bytes .../__pycache__/version.cpython-311.pyc | Bin 0 -> 21933 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 -> 8394 bytes .../__pycache__/actions.cpython-311.pyc | Bin 0 -> 8520 bytes .../__pycache__/common.cpython-311.pyc | Bin 0 -> 14842 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 277694 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 12984 bytes .../__pycache__/helpers.cpython-311.pyc | Bin 0 -> 53685 bytes .../__pycache__/results.cpython-311.pyc | Bin 0 -> 36368 bytes .../__pycache__/testing.cpython-311.pyc | Bin 0 -> 19564 bytes .../__pycache__/unicode.cpython-311.pyc | Bin 0 -> 15422 bytes .../__pycache__/util.cpython-311.pyc | Bin 0 -> 14321 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 -> 28057 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 -> 471 bytes .../tomli/__pycache__/_parser.cpython-311.pyc | Bin 0 -> 30910 bytes .../tomli/__pycache__/_re.cpython-311.pyc | Bin 0 -> 4550 bytes .../tomli/__pycache__/_types.cpython-311.pyc | Bin 0 -> 463 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 -> 690 bytes .../command/__pycache__/alias.cpython-311.pyc | Bin 0 -> 3957 bytes .../__pycache__/bdist_egg.cpython-311.pyc | Bin 0 -> 25639 bytes .../__pycache__/bdist_rpm.cpython-311.pyc | Bin 0 -> 2245 bytes .../command/__pycache__/build.cpython-311.pyc | Bin 0 -> 7045 bytes .../__pycache__/build_clib.cpython-311.pyc | Bin 0 -> 4220 bytes .../__pycache__/build_ext.cpython-311.pyc | Bin 0 -> 22065 bytes .../__pycache__/build_py.cpython-311.pyc | Bin 0 -> 23231 bytes .../__pycache__/develop.cpython-311.pyc | Bin 0 -> 10973 bytes .../__pycache__/dist_info.cpython-311.pyc | Bin 0 -> 8035 bytes .../__pycache__/easy_install.cpython-311.pyc | Bin 0 -> 121555 bytes .../editable_wheel.cpython-311.pyc | Bin 0 -> 51468 bytes .../__pycache__/egg_info.cpython-311.pyc | Bin 0 -> 40893 bytes .../__pycache__/install.cpython-311.pyc | Bin 0 -> 6870 bytes .../install_egg_info.cpython-311.pyc | Bin 0 -> 5396 bytes .../__pycache__/install_lib.cpython-311.pyc | Bin 0 -> 8467 bytes .../install_scripts.cpython-311.pyc | Bin 0 -> 4334 bytes .../__pycache__/py36compat.cpython-311.pyc | Bin 0 -> 8091 bytes .../__pycache__/register.cpython-311.pyc | Bin 0 -> 1181 bytes .../__pycache__/rotate.cpython-311.pyc | Bin 0 -> 4241 bytes .../__pycache__/saveopts.cpython-311.pyc | Bin 0 -> 1421 bytes .../command/__pycache__/sdist.cpython-311.pyc | Bin 0 -> 13493 bytes .../__pycache__/setopt.cpython-311.pyc | Bin 0 -> 7733 bytes .../command/__pycache__/test.cpython-311.pyc | Bin 0 -> 14674 bytes .../__pycache__/upload.cpython-311.pyc | Bin 0 -> 1145 bytes .../__pycache__/upload_docs.cpython-311.pyc | Bin 0 -> 11996 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 -> 2085 bytes .../_apply_pyprojecttoml.cpython-311.pyc | Bin 0 -> 22894 bytes .../config/__pycache__/expand.cpython-311.pyc | Bin 0 -> 28299 bytes .../__pycache__/pyprojecttoml.cpython-311.pyc | Bin 0 -> 27930 bytes .../__pycache__/setupcfg.cpython-311.pyc | Bin 0 -> 33339 bytes .../setuptools/config/_apply_pyprojecttoml.py | 384 + .../config/_validate_pyproject/__init__.py | 34 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 2373 bytes .../error_reporting.cpython-311.pyc | Bin 0 -> 20264 bytes .../extra_validations.cpython-311.pyc | Bin 0 -> 1922 bytes .../fastjsonschema_exceptions.cpython-311.pyc | Bin 0 -> 3297 bytes ...fastjsonschema_validations.cpython-311.pyc | Bin 0 -> 192695 bytes .../__pycache__/formats.cpython-311.pyc | Bin 0 -> 14412 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 -> 4449 bytes .../site-packages/setuptools/glob.py | 167 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui-arm64.exe | Bin 0 -> 137728 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/installer.py | 104 + .../site-packages/setuptools/launch.py | 36 + .../site-packages/setuptools/logging.py | 37 + .../site-packages/setuptools/monkey.py | 165 + .../site-packages/setuptools/msvc.py | 1703 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1177 +++ .../site-packages/setuptools/py34compat.py | 13 + .../site-packages/setuptools/sandbox.py | 530 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/unicode_utils.py | 42 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 222 + .../setuptools/windows_support.py | 29 + .../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 -> 449 bytes .../__pycache__/_internal.cpython-311.pyc | Bin 0 -> 10740 bytes .../__pycache__/_reloader.cpython-311.pyc | Bin 0 -> 23185 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 37015 bytes .../__pycache__/formparser.cpython-311.pyc | Bin 0 -> 18049 bytes .../werkzeug/__pycache__/http.cpython-311.pyc | Bin 0 -> 54805 bytes .../__pycache__/local.cpython-311.pyc | Bin 0 -> 31385 bytes .../__pycache__/security.cpython-311.pyc | Bin 0 -> 7819 bytes .../__pycache__/serving.cpython-311.pyc | Bin 0 -> 50494 bytes .../werkzeug/__pycache__/test.cpython-311.pyc | Bin 0 -> 64301 bytes .../__pycache__/testapp.cpython-311.pyc | Bin 0 -> 9593 bytes .../werkzeug/__pycache__/urls.cpython-311.pyc | Bin 0 -> 9082 bytes .../__pycache__/user_agent.cpython-311.pyc | Bin 0 -> 2373 bytes .../__pycache__/utils.cpython-311.pyc | Bin 0 -> 30272 bytes .../werkzeug/__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 26933 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 -> 3106 bytes .../__pycache__/accept.cpython-311.pyc | Bin 0 -> 18351 bytes .../__pycache__/auth.cpython-311.pyc | Bin 0 -> 15661 bytes .../__pycache__/cache_control.cpython-311.pyc | Bin 0 -> 13461 bytes .../__pycache__/csp.cpython-311.pyc | Bin 0 -> 7262 bytes .../__pycache__/etag.cpython-311.pyc | Bin 0 -> 6152 bytes .../__pycache__/file_storage.cpython-311.pyc | Bin 0 -> 9765 bytes .../__pycache__/headers.cpython-311.pyc | Bin 0 -> 33833 bytes .../__pycache__/mixins.cpython-311.pyc | Bin 0 -> 19251 bytes .../__pycache__/range.cpython-311.pyc | Bin 0 -> 10904 bytes .../__pycache__/structures.cpython-311.pyc | Bin 0 -> 66537 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 -> 26123 bytes .../debug/__pycache__/console.cpython-311.pyc | Bin 0 -> 13509 bytes .../debug/__pycache__/repr.cpython-311.pyc | Bin 0 -> 16187 bytes .../debug/__pycache__/tbtools.cpython-311.pyc | Bin 0 -> 18251 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 -> 250 bytes .../__pycache__/dispatcher.cpython-311.pyc | Bin 0 -> 3534 bytes .../__pycache__/http_proxy.cpython-311.pyc | Bin 0 -> 11019 bytes .../__pycache__/lint.cpython-311.pyc | Bin 0 -> 20980 bytes .../__pycache__/profiler.cpython-311.pyc | Bin 0 -> 7656 bytes .../__pycache__/proxy_fix.cpython-311.pyc | Bin 0 -> 7723 bytes .../__pycache__/shared_data.cpython-311.pyc | Bin 0 -> 13959 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 -> 5115 bytes .../__pycache__/converters.cpython-311.pyc | Bin 0 -> 12494 bytes .../__pycache__/exceptions.cpython-311.pyc | Bin 0 -> 8998 bytes .../routing/__pycache__/map.cpython-311.pyc | Bin 0 -> 41794 bytes .../__pycache__/matcher.cpython-311.pyc | Bin 0 -> 9144 bytes .../routing/__pycache__/rules.cpython-311.pyc | Bin 0 -> 42224 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 -> 246 bytes .../sansio/__pycache__/http.cpython-311.pyc | Bin 0 -> 6162 bytes .../__pycache__/multipart.cpython-311.pyc | Bin 0 -> 15409 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 23495 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 34182 bytes .../sansio/__pycache__/utils.cpython-311.pyc | Bin 0 -> 6916 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 -> 411 bytes .../__pycache__/request.cpython-311.pyc | Bin 0 -> 27634 bytes .../__pycache__/response.cpython-311.pyc | Bin 0 -> 37058 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 + 1814 files changed, 334236 insertions(+) create mode 100644 app.py create mode 100644 data.json create mode 100644 index.html create mode 100644 requirements.txt create mode 100644 static/css/style.css create mode 100644 static/js/main.js create mode 100644 templates/index.html 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.8.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/click/__init__.py create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/__init__.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_compat.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_termui_impl.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_textwrap.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/_winconsole.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/decorators.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/exceptions.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/formatting.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/globals.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/parser.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/shell_completion.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/termui.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/testing.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/types.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/__pycache__/utils.cpython-311.pyc create mode 100644 venv/lib/python3.11/site-packages/click/_compat.py create mode 100644 venv/lib/python3.11/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python3.11/site-packages/click/_textwrap.py create mode 100644 venv/lib/python3.11/site-packages/click/_winconsole.py create mode 100644 venv/lib/python3.11/site-packages/click/core.py create mode 100644 venv/lib/python3.11/site-packages/click/decorators.py create mode 100644 venv/lib/python3.11/site-packages/click/exceptions.py create mode 100644 venv/lib/python3.11/site-packages/click/formatting.py create mode 100644 venv/lib/python3.11/site-packages/click/globals.py create mode 100644 venv/lib/python3.11/site-packages/click/parser.py create mode 100644 venv/lib/python3.11/site-packages/click/py.typed create mode 100644 venv/lib/python3.11/site-packages/click/shell_completion.py create mode 100644 venv/lib/python3.11/site-packages/click/termui.py create mode 100644 venv/lib/python3.11/site-packages/click/testing.py create mode 100644 venv/lib/python3.11/site-packages/click/types.py create mode 100644 venv/lib/python3.11/site-packages/click/utils.py create mode 100644 venv/lib/python3.11/site-packages/distutils-precedence.pth create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/REQUESTED create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/flask-3.0.2.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.5.dist-info/INSTALLER create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/METADATA create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/RECORD create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/WHEEL create mode 100644 venv/lib/python3.11/site-packages/jinja2-3.1.5.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/app.py b/app.py new file mode 100644 index 0000000..ddc863e --- /dev/null +++ b/app.py @@ -0,0 +1,80 @@ +from flask import Flask, render_template, request, jsonify, url_for +import os +from datetime import datetime +import json +import re + +app = Flask(__name__, static_folder='static') + +def count_words_in_text(text): + # Supprime les lignes commençant par * (titres org) + text = re.sub(r'^\*+.*$', '', text, flags=re.MULTILINE) + # Supprime les lignes commençant par # (commentaires) + text = re.sub(r'^#.*$', '', text, flags=re.MULTILINE) + # Compte les mots (séquences de caractères non-espaces) + words = re.findall(r'\S+', text) + return len(words) + +def read_org_file(): + with open('livre.org', 'r', encoding='utf-8') as f: + return f.read() + +def update_word_count(): + try: + with open('data.json', 'r', encoding='utf-8') as f: + data = json.load(f) + except FileNotFoundError: + data = {} + + today = datetime.now().strftime('%Y-%m-%d') + content = read_org_file() + current_words = count_words_in_text(content) + + # Si on a déjà un compteur pour aujourd'hui, on calcule la différence + if today in data: + previous_words = data[today] + if current_words > previous_words: + data[today] = current_words - previous_words + else: + data[today] = 0 + else: + data[today] = current_words + + with open('data.json', 'w', encoding='utf-8') as f: + json.dump(data, f, indent=2) + + return data[today] + +def count_words_today(): + try: + with open('data.json', 'r', encoding='utf-8') as f: + data = json.load(f) + today = datetime.now().strftime('%Y-%m-%d') + return data.get(today, 0) + except FileNotFoundError: + return update_word_count() + +@app.route('/') +def index(): + content = read_org_file() + words_today = count_words_today() + return render_template('index.html', content=content, words_today=words_today) + +@app.route('/update', methods=['POST']) +def update(): + new_content = request.form.get('content') + with open('livre.org', 'w', encoding='utf-8') as f: + f.write(new_content) + + # Met à jour le compteur de mots + words_today = update_word_count() + return jsonify({'status': 'success', 'words_today': words_today}) + +@app.route('/words_today') +def get_words_today(): + return jsonify({'words': count_words_today()}) + +if __name__ == '__main__': + # Initialise le compteur de mots au démarrage si nécessaire + count_words_today() + app.run(debug=True) \ No newline at end of file diff --git a/data.json b/data.json new file mode 100644 index 0000000..09f54ab --- /dev/null +++ b/data.json @@ -0,0 +1,3 @@ +{ + "2025-03-04": 8 +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..aa87bf3 --- /dev/null +++ b/index.html @@ -0,0 +1,95 @@ + + + + + + Éditeur de Livre + + + + +
+
+ + + + +
+
+

Éditeur de Livre

+ +
+ +
+
+
+ + + + + diff --git a/livre.org b/livre.org index 8e8dd5d..017841c 100644 --- a/livre.org +++ b/livre.org @@ -18,6 +18,10 @@ * Livre nom_de_mon_livre :title: +eeeeeeeee préambule du cul +dfgdgg dsg dsgd gbfgfgghfhghg dsg dsgd gbfgfgghfhghg dsg dsgd gbfgfgghfhghg dsg dsgd gbfgfgghfhghg +et il était un gens qui faisait nimp + ** préambule du cul eeeeeeeeeeeeeeeeeeeee préambule du cul eeeeeeeeeeeeeeeeee diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4bf3159 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +flask==3.0.2 \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..dd6d900 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,132 @@ +:root { + --bg-color: #ffffff; + --text-color: #212529; + --border-color: #dee2e6; + --sidebar-bg: #f8f9fa; + --editor-bg: #ffffff; + --preview-bg: #ffffff; + --code-bg: #f8f9fa; + --blockquote-color: #6c757d; +} + +[data-theme="dark"] { + --bg-color: #212529; + --text-color: #f8f9fa; + --border-color: #495057; + --sidebar-bg: #343a40; + --editor-bg: #2b3035; + --preview-bg: #2b3035; + --code-bg: #343a40; + --blockquote-color: #adb5bd; +} + +body { + background-color: var(--bg-color); + color: var(--text-color); +} + +.sidebar { + height: 100vh; + background-color: var(--sidebar-bg); + padding: 20px; + border-right: 1px solid var(--border-color); +} + +.editor { + height: 100vh; + padding: 20px; +} + +#editor-content { + width: 100%; + height: calc(100vh - 100px); + font-family: monospace; + padding: 15px; + border: 1px solid var(--border-color); + border-radius: 4px; + resize: none; + background-color: var(--editor-bg); + color: var(--text-color); +} + +.word-count { + background-color: var(--code-bg); + padding: 15px; + border-radius: 4px; + margin-bottom: 20px; +} + +.preview-panel { + height: 100vh; + padding: 20px; + background-color: var(--bg-color); + border-left: 1px solid var(--border-color); + overflow-y: auto; +} + +.preview-content { + max-width: 800px; + margin: 0 auto; + padding: 20px; + background-color: var(--preview-bg); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +.preview-content h1 { + font-size: 2em; + margin-bottom: 1em; +} + +.preview-content h2 { + font-size: 1.5em; + margin: 1em 0; +} + +.preview-content h3 { + font-size: 1.2em; + margin: 0.8em 0; +} + +.preview-content p { + margin-bottom: 1em; + line-height: 1.6; +} + +.preview-content ul, +.preview-content ol { + margin-bottom: 1em; + padding-left: 2em; +} + +.preview-content li { + margin-bottom: 0.5em; +} + +.preview-content blockquote { + border-left: 4px solid var(--border-color); + padding-left: 1em; + margin: 1em 0; + color: var(--blockquote-color); +} + +.preview-content code { + background-color: var(--code-bg); + padding: 0.2em 0.4em; + border-radius: 3px; + font-family: monospace; +} + +.preview-content pre { + background-color: var(--code-bg); + padding: 1em; + border-radius: 4px; + overflow-x: auto; + margin: 1em 0; +} + +.theme-switch { + position: fixed; + top: 20px; + right: 20px; + z-index: 1000; +} \ No newline at end of file diff --git a/static/js/main.js b/static/js/main.js new file mode 100644 index 0000000..00e95cc --- /dev/null +++ b/static/js/main.js @@ -0,0 +1,159 @@ +let enable_auto_update = false; +let previewTimeout = null; +let isScrolling = false; + +// Gestion du thème +const themeSwitch = document.getElementById('theme-switch'); +const htmlElement = document.documentElement; + +// Charger le thème sauvegardé +const savedTheme = localStorage.getItem('theme') || 'light'; +htmlElement.setAttribute('data-theme', savedTheme); +themeSwitch.checked = savedTheme === 'dark'; + +// Écouteur d'événements pour le switch de thème +themeSwitch.addEventListener('change', (e) => { + const theme = e.target.checked ? 'dark' : 'light'; + htmlElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); +}); + +// Fonction pour convertir le texte org en HTML +function orgToHtml(text) { + // Conversion des titres + text = text.replace(/^\*+ (.*)$/gm, (match, content) => { + const level = match.match(/^\*+/)[0].length; + return `${content}`; + }); + + // Conversion des listes + text = text.replace(/^- (.*)$/gm, '
  • $1
  • '); + text = text.replace(/(
  • .*<\/li>\n?)+/g, ''); + + // Conversion des citations + text = text.replace(/^#\+BEGIN_QUOTE\n(.*?)\n#\+END_QUOTE$/gs, '
    $1
    '); + + // Conversion du code + text = text.replace(/^#\+BEGIN_SRC.*\n(.*?)\n#\+END_SRC$/gs, '
    $1
    '); + text = text.replace(/`([^`]+)`/g, '$1'); + + // Conversion des paragraphes + text = text.split('\n\n').map(para => { + if (!para.trim()) return ''; + if (!para.match(/^<[hul]|^${para}

    `; + } + return para; + }).join('\n'); + + return text; +} + +// Fonction pour mettre à jour la prévisualisation +function updatePreview() { + const content = document.getElementById('editor-content').value; + const previewContent = document.getElementById('preview-content'); + previewContent.innerHTML = orgToHtml(content); +} + +// Synchronisation du défilement +function syncScroll(source, target) { + if (isScrolling) return; + isScrolling = true; + + const sourceScrollPercent = source.scrollTop / (source.scrollHeight - source.clientHeight); + const targetScrollTop = sourceScrollPercent * (target.scrollHeight - target.clientHeight); + target.scrollTop = targetScrollTop; + + setTimeout(() => { + isScrolling = false; + }, 100); +} + +// Écouteurs d'événements pour la synchronisation du défilement +const editor = document.getElementById('editor-content'); +const preview = document.getElementById('preview-content'); + +editor.addEventListener('scroll', () => { + syncScroll(editor, preview); +}); + +preview.addEventListener('scroll', () => { + syncScroll(preview, editor); +}); + +// Écouteur d'événements pour la mise à jour automatique de la prévisualisation +editor.addEventListener('input', () => { + if (document.getElementById('auto-preview').checked) { + clearTimeout(previewTimeout); + previewTimeout = setTimeout(updatePreview, 500); + } +}); + +// Écouteur d'événements pour le switch de mise à jour automatique +document.getElementById('auto-preview').addEventListener('change', (e) => { + if (e.target.checked) { + updatePreview(); + } +}); + +// Sauvegarde automatique si activée +if (enable_auto_update) { + setInterval(async () => { + const content = document.getElementById('editor-content').value; + try { + const response = await fetch('/update', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `content=${encodeURIComponent(content)}` + }); + const data = await response.json(); + if (response.ok) { + document.getElementById('words-today').textContent = data.words_today; + console.log('Sauvegarde automatique effectuée'); + } + } catch (error) { + console.error('Erreur lors de la sauvegarde automatique'); + } + }, 20000); // 20 secondes +} + +// Mise à jour du contenu +document.getElementById('update-btn').addEventListener('click', async () => { + const content = document.getElementById('editor-content').value; + try { + const response = await fetch('/update', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `content=${encodeURIComponent(content)}` + }); + const data = await response.json(); + if (response.ok) { + document.getElementById('words-today').textContent = data.words_today; + alert('Contenu mis à jour avec succès !'); + } + } catch (error) { + alert('Erreur lors de la mise à jour'); + } +}); + +// Mise à jour automatique du compteur de mots +async function updateWordCount() { + try { + const response = await fetch('/words_today'); + const data = await response.json(); + document.getElementById('words-today').textContent = data.words; + } catch (error) { + console.error('Erreur lors de la mise à jour du compteur de mots'); + } +} + +// Mise à jour toutes les 30 secondes +setInterval(updateWordCount, 30000); + +// Initialisation de la prévisualisation +updatePreview(); \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..55d5773 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,58 @@ + + + + + + + Éditeur de Livre + + + + + +
    +
    + + +
    +
    + +
    +
    + + + + +
    +
    +

    Éditeur de Livre

    + +
    + +
    + + +
    +
    +

    Prévisualisation

    +
    + + +
    +
    +
    +
    +
    +
    + + + + + + \ No newline at end of file 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..1d61797 --- /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=/home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..1cd3d9c --- /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 /home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..a00c591 --- /dev/null +++ b/venv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV /home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..8c47300 --- /dev/null +++ b/venv/bin/flask @@ -0,0 +1,8 @@ +#!/home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..f03ef88 --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,8 @@ +#!/home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..f03ef88 --- /dev/null +++ b/venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..f03ef88 --- /dev/null +++ b/venv/bin/pip3.11 @@ -0,0 +1,8 @@ +#!/home/poule/encrypted/stockage-syncable/www/development/html/book_generator/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..898ccd7 --- /dev/null +++ b/venv/bin/python3 @@ -0,0 +1 @@ +/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..aefddcb300487ffe9be12d5de54fcb3d16b30e8d GIT binary patch literal 11211 zcmbtaTWlLwdOkxAso_PUBucg%-zJjdSiX?H#g1dg&PBF!RZ`1I6L(XZ;*2EP6v>_$ zNfsmTDp{kE19js9No}A>pXk$)X6uV?Ik=*3C?N@n#QGS`{LG%3T**}u{` zN%QFJg2!n*$i~>u(h%$K{FZtTT1q03pUzJw5-E2yWN1G6uD%a|J(5iP zI_ZMsZcgOQ zTrOkmR);6dN_{#zT2rGYGe%D3dOnj(>4s{K>FRlR((~$gPMgT+YC5Z)H>Qo4{c4<# zsb|O1hB}^{Rx^51Q_Y+@k=1k~&6C4uKCF)=C(}7@s5!3coFj)GIW;+%OQZ3aZeU2m zn9zZkT{dA5TJFTiaXn>brgy7))|kLr%(0}Y8t#J79Y`5wGLyl2fgT}l@}!nF)46Oi zgZ-FRcj&Rvn3~O*YBH>UUS;W4UoXp3h;k<9as5 zr}H?+xMAi}7n7s<9%DM2BIM&!Q&VwGpVTwC{J5Sq<74J{CO(|YT}+JXS)C`%9FI@x z*~xe&Jsi(Zn`61`f!Mx%aU*T&d-6#!nh{U9=qJWd7Eb`hw3$f6^3&Ej!mg%4p5wH# zCXWEo0Ac*+0JChRrSp@%k9QSY9>KGsw9WZ%x3ra+*BANdKq=a{FtQZgU5xH7`&l3| z=U?k$%kREi_V@xP?s!{#{<{pITn|<;14|Kb5|KWAS8oFRFpFwn)Qm?k z9QA5SnzxDJAn@u~*=5E7Rxf@oOEVJ0Smd&2?e;UCC)s>^g@HNoyI|KsZ zDg<2ui1kZW5PZZHJ;rSO&5tl^f3=FZ89r^t?(V zv16HB3UcH)GESpjbTWl zPoSXeV}aJML>=CEJBH|&xq=@~w^FHBZluy;=b=UUa7jK~ln<9Z4*p+vt^e@FvJbC!Xiaws%np=;tfRZkB;OVR=H%Pq z$oz{pbm zBoM&x>@qW{tdi>4R$^w2?yawTj7g-MYx+84Fl=T$FOhDhPyMz_EF0=$`^{5w1=x!ieMs3HpbH9R;yi_uoWK} zS0m|+o=8-g72>83I9W1HS1V4eb+%eh2okE!$9JIl0ep@B1^|!BT}9{lT8=Kt-6grZ zD0lxc$bxNG*UhgZX4@mciqf&HY+X{eE`%19-6dsrQQ1vwXV;1*cc}4Qw@0;aL+;+a zdkrP_tHQ$F%c0(-P;asCz+&iNDRgjlU?sHv#=(!DEQWU2&&_RL>{$%$D2ex#(DvV? zzPMNn9cg%s4y^B&>z?*{zx2vax3qj2lmJsGbQAF~k>n~VT*!qQ_N&f zj)j5jDg3kG_LDWn7Fkr{c+^xbKV2^}puk`kjKH*m^_7F2qZ+0L@`we+Fhjboj+tiO zcp@Gjg;tpujzM$49?2);RXU5?CSd&FzQcVYi#8;I_8d5}fB%uk5ANM327@UJGZZG^ zc+N~uCP{wTqG=EsK*in&(?n3tXG};6Ti%4UT!K*JX-(%OZwBx+9tVKTX=6&{o#`vn zW#;icd|TPFsHi1HEh=hl9Sn#GWFCaVu&*y~JZaH-fik0!zO@M<1FS@VJo zW$@Zro}Nr6GiUTVHBYBZHvMXs7-2@5VF~2yL@fN7Gzf7TNaT~Isq-ux0kEH*8Liz`g|;nMh*oEeIfZ|MaSc+QV66=g&&l&`bNJZns?{(unh4sXJ$p~8r@lF9M8XP{ z8CG?U8m**yp-G0vVBNB5aN_e-72qT3MM%o)WZ@`e;av4hve(&l$k6!!Z2^y?5#I@b z6Q_N$yjZ*CH%v|jHI1dJv$mZQI7Wu>r96k3QnLZ$Ni#K8W2ZQcUPE8wQGk2juy3#{ z#m=L67KW}JxUv1(llEIJ6kCNO@WS!nd(jUfZXbU5VH$|GP(5#xpHEC#Xm3Q~EHxxC zcW;*6j&#-zeskc9LA)<^9xVYzj+P=vi^@?k~r#$S><=@>CjbDj!VAPH+5@<`l&KcgTPWJ@2glv6i(VA_5** z2~}3mV_FBM2)2MyS8#Ki%yEQOdAvwXTGNF|=xBT{tmvok09>?>$*Z=8_-@akz=R&tTdTw;xc>Cr{H(y%pI8y33 z0_Qf;JvVvv()^{lh~SVqK}SZXATAZ>@t&82+yaW4Q~gm_0!Pp$840E#{dy|D-pf(| zhT%dj3A@8Jnyc@7vmJe`)==EWxJzXWZ zhB_3x%8#LfKS|&W0aEAKaAD@qQf#BZin#dLXUWOcrYL|xU9l<7r|j{xZiKDZ3>2xg z8#=KG2z2=C7^ZUCmOsbSqv>pa$O5tylBtQ+ZqoqIjl*>!vgF&*2>}veg!B;_0vE9ZBq1OvpRz?|XEXT} zw!0g1Uos=cGrj>J`UyooIPw08#n7fwXcKlM5VeJ-(o=Mv6=hS=c~+FoMdvBYA++w? zxZK&l)Y)I$`SfDvGo{XF=ANB<_TKGCPniV*(HhXnTBCEP=1!HPC?}t6oj-sxxF5KY z{&>8!W&a&&bhp~FowaY6|LJlhwiJo2gxBBLdSmP2hMlDiJ8vEM?Xj|#wa4!;PkZn# z0i1pyD469Rx{tDd2|gY0eyK=+b<&4;m%gh{0X%5Xrr9_yToA4f4oe-H$WzGGKtwv9 z&rH`v2vzcho_$q>b=4ii6X}dbL2Q*Q0;AvdifD{8`iR=M|Hz@oL~Y-Jy?YN=D+_J; zY0(ui_LzCegk;);Mex%AmOpKf6W?GS@HbFb*s>O}R7v~_+87%E;9iAUd*}Sr2S0uP zr^PL?#Ynsqi5Hc);FUVwH)eS3iU6Bc9lZAszTznvVKw7P*OG&l?^Ms zv4!1pa!J`*6i+j8kP#w?V+@)1$b?0>6Hz{?_UMJShuH#y$USZ}cT=N5G|=E@H1VQb zc*W(#0o_EvR85Z%6;RZESSP}8c9ZU%lDJtTHZ)Q^oi}3@);sXnV^yLN5x9Eymn1W} zY9hE_XtW^F$_Wl1Z!(bPT`TlQ)`{}_mWW!B|2X9Cm6*z1yJ#-AycCySfj!Jia&94 z;+8h|>~gqoDcrYkaxuKK6y90(It{8#t2sd$Amsoq_)_{XZmgghv(r{^Dw(;Mz~x2i zB21Gk=Hoegi^+2aYNvA}E4ceud)aelFq zREc{C8kzRqLf+lNAEip{n-^P8SM*9njaMS3q%&+wFVoWXxgKQuKYy3gNFKIyVz^`_*t(mXg#EA)|_)1DAip*VqPt7_Z#* ziTC5yqWnlvKJ=T7pKbnP^G)%=tNqyWsj>p`<4BtyyjI{e$J!QkFKT{3w7H9y_`7J` z#L0m~0@pD*Pb3O$v@~2JRNnss%~vU)fb}WStF7~`bK+w!MMi~_+=F`{e5?@H$8mWh zcC_N%T3-E9%JNMnGZVVyF^3(?#a8qb9oH|>pI8d54zA*L37GKr2-u>lDRA(YRQFc| zNUhkU*hV?pTLJzZnKeS@;_|Tq5HhcQMey8ywTBa@ghAXyJ0uhkMdKgTeKbkZRZ_hT zU=uX%T7=2z{B7bLw1s0QXqV68rE#I+@Cp1UzQ)4!gdr{s~ zlJ^vy$3AGZbd$Rzj-u=MtB~ndv6_pbwat{eC4u@scQ~NJqX=P=*sP?rLYTIw_Sw?a zUa?I=V#QYQbt0RS^jEaT)nCP^oPdR|uv%eSc)Y&W+e&D@by?Z8q-^@b<~@r_tfa(> z&U5c}sGIIcTB~413D3!MGF>{iB3xn6|GVDZwu9Xa9`gQ9I^^x|vaus?+v*~>!AxhJ ziyZNX8&2xWzRnc-Ri)P*1a=Xin-?J^IR(YUUtX*h7+n-iw{^=bm6HIniB}w~SYJJ9 zBiwIC>W=e|(3m#ccpDI?OVU>?I4eFYEHEoR2$+YuZ+J^RdyB!nvn^$RyM+JqxL|u& z!k=DTu*D}KF64stHtC5nb3t!F!ey!pdVCUYnVP{JD!W^)XxAi~b8UD>l;5qb9rUtR zwG@VG@=-qk+|`z7fx4%-2WPXdcK1HybAVP2_im!ueVs{looKr+ohFx3A74fYoO literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/override.cpython-311.pyc b/venv/lib/python3.11/site-packages/_distutils_hack/__pycache__/override.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..702b914706c99978040d327bd1c4f258d0450725 GIT binary patch literal 368 zcmZ9H&q~8U5XL7hNJ%Mu0eiR9b|_v&d;%{%z>;Q%B;?O7yW51^y!r%QJyoO+;R^2~yxMlMM9Uzdf@&MLczj{8o zHfj2bYkdklklsCvJNu!KiFHetWLCsMnBH;b3z6hn87IWPFO^Uw8IwqQg+nvo_=vH} z3AI{ggj9s4){Z1vr@}OdXlm;s3>JJ>RTWAqDN{P9!eQ+43>QkJBBFv!;FQ6ViW0MA zfx33FDz0YpIoib0R5J}vv-pn?Tb!A$kG<<$NyfM_Jtk{DZZCNI?s}g03I2n>>7Q?5 Ww1d$HjNf6rg~<*kn|7Hqe*6O|{bkMo 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..0e18adb2958e62bd53c2997d94821fec00cde9cf GIT binary patch literal 659 zcmaKozl+;26vv-p$958qDS|ZKRcTOjxXmw%Xb9ecL+{n^aSLgK==v* z1W{0voDdKr5vfrfv}DrZ+I3 z-G>k7B`iSHfEzFm3nFSjhBKtZ2B8osEugvQKH4_8g1*1HMeM A1ONa4 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..6d69745d4bc6f5295db5b656c619248e5e617d25 GIT binary patch literal 3144 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 E0BkJJ&j0`b 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.8.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/LICENSE.txt b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/LICENSE.txt new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/METADATA b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/METADATA new file mode 100644 index 0000000..366d1a7 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/METADATA @@ -0,0 +1,74 @@ +Metadata-Version: 2.3 +Name: click +Version: 8.1.8 +Summary: Composable command line interface toolkit +Maintainer-email: Pallets +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Requires-Dist: colorama; platform_system == 'Windows' +Requires-Dist: importlib-metadata; python_version < '3.8' +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/click/ + +# $ click_ + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +## A Simple Example + +```python +import click + +@click.command() +@click.option("--count", default=1, help="Number of greetings.") +@click.option("--name", prompt="Your name", help="The person to greet.") +def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + +if __name__ == '__main__': + hello() +``` + +``` +$ python hello.py --count=3 +Your name: Click +Hello, Click! +Hello, Click! +Hello, Click! +``` + + +## Donate + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + diff --git a/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD new file mode 100644 index 0000000..e38eddf --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/RECORD @@ -0,0 +1,38 @@ +click-8.1.8.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.8.dist-info/LICENSE.txt,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.8.dist-info/METADATA,sha256=WJtQ6uGS2ybLfvUE4vC0XIhIBr4yFGwjrMBR2fiCQ-Q,2263 +click-8.1.8.dist-info/RECORD,, +click-8.1.8.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +click/__init__.py,sha256=j1DJeCbga4ribkv5uyvIAzI0oFN13fW9mevDKShFelo,3188 +click/__pycache__/__init__.cpython-311.pyc,, +click/__pycache__/_compat.cpython-311.pyc,, +click/__pycache__/_termui_impl.cpython-311.pyc,, +click/__pycache__/_textwrap.cpython-311.pyc,, +click/__pycache__/_winconsole.cpython-311.pyc,, +click/__pycache__/core.cpython-311.pyc,, +click/__pycache__/decorators.cpython-311.pyc,, +click/__pycache__/exceptions.cpython-311.pyc,, +click/__pycache__/formatting.cpython-311.pyc,, +click/__pycache__/globals.cpython-311.pyc,, +click/__pycache__/parser.cpython-311.pyc,, +click/__pycache__/shell_completion.cpython-311.pyc,, +click/__pycache__/termui.cpython-311.pyc,, +click/__pycache__/testing.cpython-311.pyc,, +click/__pycache__/types.cpython-311.pyc,, +click/__pycache__/utils.cpython-311.pyc,, +click/_compat.py,sha256=IGKh_J5QdfKELitnRfTGHneejWxoCw_NX9tfMbdcg3w,18730 +click/_termui_impl.py,sha256=a5z7I9gOFeMmu7Gb6_RPyQ8GPuVP1EeblixcWSPSQPk,24783 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=Q1nEVdctZwvIPOlt4vfHko0TYnHCeE40UEEul8Wpyvs,114748 +click/decorators.py,sha256=7t6F-QWowtLh6F_6l-4YV4Y4yNTcqFQEu9i37zIz68s,18925 +click/exceptions.py,sha256=V7zDT6emqJ8iNl0kF1P5kpFmLMWQ1T1L7aNNKM4YR0w,9600 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=cuJ6Bbo073lgEEmhjr394PeM-QFmXM-Ci-wmfsd7H5g,1954 +click/parser.py,sha256=h4sndcpF5OHrZQN8vD8IWb5OByvW7ABbhRToxovrqS8,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=TR0dXEGcvWb9Eo3aaQEXGhnvNS3FF4H4QcuLnvAvYo4,18636 +click/termui.py,sha256=dLxiS70UOvIYBda_nEEZaPAFOVDVmRs1sEPMuLDowQo,28310 +click/testing.py,sha256=3RA8anCf7TZ8-5RAF5it2Te-aWXBAL5VLasQnMiC2ZQ,16282 +click/types.py,sha256=BD5Qqq4h-8kawBmOIzJlmq4xzThAf4wCvaOLZSBDNx0,36422 +click/utils.py,sha256=ce-IrO9ilII76LGkU354pOdHbepM8UftfNH7SfMU_28,20330 diff --git a/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/venv/lib/python3.11/site-packages/click-8.1.8.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.11/site-packages/click/__init__.py b/venv/lib/python3.11/site-packages/click/__init__.py new file mode 100644 index 0000000..2610d0e --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/__init__.py @@ -0,0 +1,75 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" + +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import HelpOption as HelpOption +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.8" diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ccf7f0086e0a57a0a65623cca32511025e1968b9 GIT binary patch literal 3778 zcma)-OH&(3630uR7eWXy#&1kxFmEKDHed|qX)|L3Yv59sj#jHI_0q4XZox2@-S4o6 z{RkWTCHA`4K6dD|5qsL3Bjz@z$xQKZg>+cR`0H1xs?4nHQuRN2dU6c@{?_~NYM5v2 zzc{%4>$rj6#yc7NJF76xDv3&mop3sMM*_JMxRZAhCxMeZNt^;s@f2|yIL*_<8Q=`h z5NCn2JWJdK+{L?ybHF*CBks1lojlJI=Ye~84{;B0fftAiz`eYexEHvO_YwC2_w#<@ ze&7fE0r3Oi0X{%H0Q`_YBz_1y$OnlBfgkZl#E*a<^T))G?I+Gt{*?F$@H765_$lyn z{+#$3@C*Ke_&M+pA0mDM{F1*U9s(Zb!^AIvHLej41CQ_#V$FW#jPg<95#TXCM*PZt z?Tqtr;!%6TndFniWA>CY&8LZ91JCdo;&I?vK1)0SJjdsVCxMH+NIV5x;w9o~;CVhz zJOjMI7l>zp7x^Ob9PkofA}#_i^JU@^@Csicp10pPZ~0r|1>jY_O1ucX#@C3KfY`_2JBAl?H0$UhQ)0RF^35pM$@@m~2YR4+HI6-7RY8u5Dci&4VcNCVDWdS>Z&Wm5o4D za)$Kku=1{u?UO@DX@pwE6M^P>AqE%Pl@-@=-oA8`}h9bCm7x( z7{EsBz7Yg^MVOv6LJw1=@51EiJ4kU;be6_m`Oh$`7x~JQmHX(0OCbZbj_tB1al3sx zM&-6|=Ydfb;46TyS<9^_51t=4U7*9X|BESZH`aAv*{qj`U02fZ^_%StR7I$pbt&QD>i4_OH-kZzfF4E4w1t6K0vJ>B1fVeR9B}rc6Cc67tIP9+OL2Zp ztri!Gt4C8`8W~-$c&4s5l5kdqgx4~YNt6^y8YP30Md?Dpx4Y~HY2@w>cp%|T&twlu z0i_qE52YXF0m=Z%LzF?3M<|a$8aZ)$7z6nPy-!h|p*%-I@ zj-dAydNWnqD;stoM{$()>4?cO8o&W{>Xv+slgCjeP$p5PP^M94P-ao)P>LuelzEUw zDuhQG$OUvPqAZ~-qpYC3L3xX^in4~Xj`9v=1LZx+CP*Vy4=t#43mqR&wo!Iac2V{~ z8r`~ndkN_OWWRxn{r;Cy4X)Xe@4@w760Rw){ZLd&LFkzm@MD<^u3Zza*wWS2RjDE_ zh3)xxzm{sDW0%UFccE8>E9iPET?+TI1TTz|Pj8i_;=)2HutG8C8x$=lnfL-K>AK}w zp{^JG>)*2*&3DhHJcWAj8V~*j2j_cdB9ZvskxC@LGn4{LOhjz_M~m5Pq*~0zBGqEH z8mZQ9jutV+Vpfb)i`lD4wU|vtszLAZs&FG>inUv%q=rh`&1vnk5*D(=>J}(YYd79ROtE%Pa4TYpwd-o@ zQ*PaR>%Nr3181q-Gi^PYt+`se@&Bx9jni85aKsdg*=VF%%;5K>SgbCA2r(OpREyb6 zq*}~|BGuYOo{E@a?Q*qN*qVJVVv4nkqimdZu@W)GVl@cFjM-YGTC6UC2(h{a*wKFq OgMaPDfB7f4$Nm88*jt7G literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/_compat.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/_compat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22a912f6132f2b4b8900500ca24706141b09f171 GIT binary patch literal 28720 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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..c94108894e4a7f39571e3a79c6603d234e75ec65 GIT binary patch literal 33321 zcmd75d3+mJo+nm?vv3gr0p1sQlR8Kp)NM)4L#HLmwq$oVd)+j}0!2!^x&Z26gKpaE znLt`j3@Mxyr$^pFCvp#atx1%mCs7jbjHlghdv-p_08DL!ARi{&Y_z*hKG_c(w?ENG z|7^a$S3sc(BxTLcd_J23@aomO->dh2_j~wbm&?xK`j6b7U;68}IPPE2L+-L=JzxK> zk>l=iA~(Q^yl5Eb2Y7Zj3>etmIACOV(}0QH%>!n3w+vWuH;xMv!hnsZyryycgk!+L z{N{1zgloXX{Fd>e3HN{-eyb>qdnUXCUgo#KUp!FE{C4<#13u<=!0#XMGrtr5l7SND zcfnseP|Ey8@RtpgF~1xB@_};Z_l#FeR1Q=!zjwT9qI#g3=L}rXdbuXoak2R4JjZ>6 zpK=Y<291~Na!;b~ih=x+S@aJC#FByfNt0L#U)eytfjhy8K@0os%sE=~d+`t}jJFC4J<#wRly`tf~vOe|=>|^EcAK3rG<##@}{2jUS+jr0Y zx&6ZESST8(K$8Q8?LP0Sw zGBY_$#Se{-g>MALLiXwLp<#rNO`^bjqlPBMz|9V+sdMm~uZ@lkkHX`+AffP!L&H}t+?Wo2Nvjc|{y{M~GBh(D z9;Cd3p|ChLLq%A6zklMpr>I;n${oBI421`SlfzRY%BASB&`>yh13t&pbZ`>+q~Op5 z9_{drO%D!DhQ{zD&~Oco2Pfe-D#aDCaXEHpC@P&y}HykP3mIA`gF0z%M3|S{km{XJ1+6M7$INYh#~LK z`$Yd{>BSOVjPbG~*KbYkQe7Ht>&t>xu^hh&ksk?&l>iG)u}iGR0&40|y0}V|D4@hvlwXzgx4~bX^|!-cll5q9J|er2qDkb>bM5=mj#s3q zOHwct>KT&ypYe^)_`ox3bKAussXg?}5C~j2E?F_KU)I7&3u9QdLl?(`X$w~FrSNFl zHZnFoJ~%u&B&F@aiRthS#qUIZfDJ&(p>Pn{CP$_QL&52^5E`AjHW&;KrJc+-9h8Ov z^|Im9Q=xPbs+bsLkpu(N=JBD6!SS>S^#s%A;i>T{Deak=7E$it#2A5>;B*L}Y)nLJ zEK)E$BTWu_a#I0!3w}feeC=T%A!3YhgKBidgeR5yh?w!D;=hOmPn45g5i6e5DH;** zq=Jcv4Np{$lG2VR8Z+g|F%23HA%Ys>oUaZ0a!(wm$98khh;zOuT=Kkll%_7#hzn27 zTo?N*n(SRp)=|$Xla_8bAZqcAnR|r+dD`J?h6b+yxy%WWA9-`JFo(QN(J!LRw zh!{jumNqkp9G?04lgR51x8};{IMJ-9?cU|X?fKZtY7fJ0n$XgmKirY?aa?}Uhj->f zBL;o>1#RTRD!svR5ni7beO3#N&?r^r%4K6#m3z9xA+9?26ybP0^IZ5)E`;Oqw5kjMc5So_nQL{lEv)}gHF!O^kF@R$D<*KBQWy$3+!D6ybL0z|8fNkQ>=dz(bv zk^VsJ8TA7mwtk4*;Ky=hY@I6fi~+rwJ%Hybtm zSg}!I0}%3}yg=dg?C*Duf~M@8o&wd{3BpXeF^ysE427qLuMAxZZV%m<93~jvdF|S@ zPBC~jI6gH^?{O?VI5_LqAefF^D0L~c0KhxXWtzCk#;9qb zC{@{nn>$tA7B$I2MXEf2M_2Av5L&y95>=%t>z200cOjvD&Ebx|wCZb3`r2h*d$cbj za2|g&vRYPmdvf$tL^)Js+PvmmD{l~u7m3(m(v^@>oP6l!ImHX+oe+`gzo zIz{CP!Ry0=VL*?xjeGz$Gr_bWd~ujyQ|?kbOPJ^`njO!@=#`=a}i@MiFuZ+F6x8b3lT*h6wLhdldWG}G*O}>j49H((ucNO*;=``i!lk3y57yqo| z`%^QFNezUjh}#Y1-h2R5Blzpdz);}YSa>vWaU3A40|UqAiSxCYNdnmn;!9^xN7|+W zD(NhqwNr)wkTPQm0gw_($&bLngmL>8A{maiy~?i^*Cy)DC5vB?i(g4NU%_fyKZo9b z`_|h@cb)96O9*xA$C`*jHr5B>xyyw$OF}!+5l)Y&^-t$H={&Nx8`7pp@ZQn^JZ#iM zid+w3mC$+Q36;Z{=e}_Q6#jnSlK=MU#naDeJGGm&JqnM0o=70`&eP0M`?K-92wRXf zd+GZ`3ty9)=KZ=$KUO}F>O*QqHh|cd@M_bx?&BAZy*Aj>{aV^QGCmU;EgT`~ z0A#t|Uf(0?hH91w>n{IoGNGa&_;55#Zb z^hy^KG#Ug+${-Ds2F})Mhi-lRA_@zU9STc`|A>O6xV>6Ht9DurFM5I)UfG)cM&5HyNF z3%yyXjtxga2U6guT1uBSr#8$dDQpu z$z(@g(swN3JeG17M?>p-DWC|pp8gCTeJ`cgH(N{kIWotCi{)prGKp7(4}7pD%%}@9 zuyiJb8Ps&fD{M7N;D-N@6HO75X#PVJ_%mbnZlL=IR)ENjW6T&+#I_6lU(!PQk^nQ~ zyJihyAZ^&O>luGgB0{6xC>_NuZ3G)65m|%vdz=#Qp-^im2syMEN?Wm-XTm{9K1Qcz zq)>>~0Fe<{I>HX2^u!QjXl6^bQ!*bOM~={c21kW{4%^XHk1y7@c=EPu(G~4Zm6k0v z+#ZRZNI6}xhMOlh4DpvN8Ezks9?Pe3dty6p%|vHXl~swdUVN8klsnwzR@M9Pn(9q> zde%+ z1H-IKnI#I@!gsbC0TRNJvIJ;ZfP`i5hSo%gmRI5UgW240{1Hw=A0lzaJhxipjWsQ{ z-JDpMh#CnM(Nak{-3eb)EWG$*-0)30o1(q6LhS2DfaWG!At&M4d;~D>F;Dd4AQ~`_ zjUPasBXYl^5g?<_=Ke25ls9V#bUovn6=Y(NLI{#Z$SK4fxk*PTWTQ!k@IOVq&{jC; zba6>cTpW%2ZciqQo8{u>gnO&{UG84)Sq9?hObDIpyPF3Hpholn;hmQ@0|+`mw{92! z3^WKg!Ul@OTnMG5#V&0LNRb7WY?2rz{{XQ7FUkclp)E}dVo}35MW-W5nvaDcno|?eYzTr+ELI78}s@FqzB?tE^UeHYZQ%))G*B=F;cSnDBt>& z1lmM%Top%Bs@xSZ>L(tJE+(0!pG_M+j z!`dVil{NwNji!ymQz3=mF73YDM+Zg?ryyHa)N>Yj!0ocFPsJqo-5FrHdW$gURCUSinv<2&SWP@&4t9 z2a_#_lfENK=aFbHVqD&ZH#3~WR3-Yt1$ld4vY{_oaZIi__JuK7 z@$whL$%uU)HU&F0-x=5; z(n7xu=lDy6YBd!9JN5`a53zZk3~>?));vqC5kp*^T_{_*p8v z4gR?$s_R-U0G@9tQM<Z%MquP3%#9_{^G>jkt?u6K4~G}NbDDBaNl zbw%sP0x-k)PRXXDTd*=2r>3r9lnOMcT&TGy=hxo#tw#ns3a)j-lqDy@rS;Sju}v7+Y!7~;UmCUL2!nVe(RwIV*LZI(QME04M&-zMq?{#> zoz*K&z@R@G{OMq_rbDjjNIE-ZXJ^9MnR1j7xACp1vi#i+0J0yl3=jK$dG^I}%8uHE zV@s;M`f>TzmGZ62ee$-$$?_v|`H|?Ul)F6PZc2G79(w{SoDelKwkAAVGZxO} zm7O(ffLE31@!g-?`AM>@4IM{G_gs(5x2%+JSw4^~-y@gr$yiP9q6`NIkjho`|2jE` z_g2fzwuQEg+iLTzrxh@(6d3id0a-|7DRScq+)*VN(oxJ?QrwSip^40@v^MZ%GVlzCWkA7!bqWDX`@s8fB`V)M-)!Ov0KW^i%N6fVm) z2RD?>Z;Y??WoTf4i6|ev*kR5L)v56cD^@xJII|&?2-DikUV8Whh_gu^k*FONhODPJ zkdu_QY6|wGj+Jg4p=isO^bXXy`KLL{X7xX}&6~hs{m9K(b#Kh7@A({IM78zrIJ8d@ zAv>a0rfybKZPwOELD|n8RZB$3QLy?JVNRMhhQozWd(KKq@%+lku9l-rRle~Wq4X-= zgET3Jn5wWgxfG-wo!r0`|*|&|~CNQ6^(juP%z01Eu zp3wiS;2ohP>Y@)J7sy2cSplUz{)L}_p4_tH-j;B0OEt9I-x4z|x>r4ZD4+&F(vCe0 z|8h3r=}CHeWKRz~Ya~ovEAm8**@A4gMgr<~;Dd_FXy3x=)tctG__*chO3Tq?OSjz8 zovi7RYkH#ntL0To-Ah*=*X>)W+n206Ak(+|lm2AgYsvESa`}0NQkD*^xSJSW@!hrG zv43zd>1mNYEeTIc%ELmIcE|nqYm-%-NzV@1vm@czk*cRw7o{p1sQ$Im%Eil32b2FM z9L+=$cSK)a6CCf`Z`ptUpjLVG*xk0`ZcDni$nGss)2gp(sqglY#UoK6o4Fn`&>ub= zU1>g&Xg-pvX-4t=*@9wSNugX8$`e9)N+~+Fdui*kkgVL1^zBRvyJTTkLf8fQ#{1W9 zU5kZoMiwGb6NcRBA#P#C(Le%$T59pRRfPGM`tF@tzVKk+5yWOaNoSAj?13lc^emiu z|Jz7lMcbx2c1bg-UK(W-taqeK-D5SRj+%W6>65Lzkk<|SyX zbu{ghnqDk-9!ydF+8z=!3>LoX-=!SJ66JxOQ7?0e7%uS&ldZ8P(y&k>H$x+-jvoVc zrv3}kFa~Gr87wy1g}iV|`VK-RV#%c=bKv0{#&km?w}G6}<}pjI7Fa zV(3bcSy$;*u4=Fk6D9O9vVcq#oKayxh@D6ZRpe1A)$sl654(POXr=W?qV-6sI)M3m z_6beWn=dcCywr4Wd(zpuynDsbk#KY{#mf@_2iqSw?m3{sb!F_B{|oywoYA&z)nC4N z>h{ZvFB1St`nNqa{ZdH!_DB1oeNTL4iwABWT0Df6UYYc5jrOe}WdBmnQtwjl;^BB- zd@pPQP@q5*X4P_EqJp&MMNxd%ieTjbusRdbCGykn>)*h^YA}FYAS)p}DHmHG7=Y|k zZhhoKG;a-aM_p;z6|oP5o3_4OLAupbh?bE@T@z{sc=Rg=NRV2pwuB`4%+${~REuW3 z&MfDcy>gD}AgycQ;*G$Ncy(xU7)HE-p+IOlI6O8o27BVknTd-*30BK?1(^f_Y_4nz zFw+c1LRN;_RX+@e(No*SC z4hH&j6)P2zu2^Ydu%j@Kw#I{jbJ<1(h%cjT)HIky7q(0-g*paSjWu7fEEEG9G_a#1 za5X4}&}s;bU{xd@JQ&#Du|ro(H*9~zjmKds*DTggSUO3X&c8_6=g7`m!P$Xpqd_tR z59VJ_c9bT9!ElITbj^C}twM`QyqNGP%sxj!YvjkXU!j`J3PVi7X=a`!{fvC1ao0i( zmPijYEJ`)A#ac2$32VoU424kyOcw&2vpnHwOa-<@`-t%))0TP|;l#h26t*c|&IQJm%u`{sZ3?!Wmva=!KY)G}i^hb6! zC)k$|-w|Y9&lb{(WGj3JJcX7l%uX)9f@nRdE11DtWB>6B7z!pz=tThvs4bL-TNJ|& z{b(p*y)+utY&238wFHd_Ix1#QWcWup7z>VzY%wuV5(4~Tt9y#AJU~r#jfpd~se-nMKvFcrHf|^YQknZo89I2oWoQHt zV2f_0vibl%nArGGV|Fpp_Ykb`EzC@W%}2I$X~9bW2{|9a z$?B@o2I;C+RV95Nae5T5j>AcsrN2S^zs3jawwzdijZI~;^t}i4eOcAwjf69>*_SBp zu?%N-)iEb#NHw*@OtPmQ=-yv0`?fvgSA07YzMUz5`D1_EioY%C-y-|BB>Y>}O3Pyc zeNrC(UB?~AQupnm#iAHKYk&?f-+KAx*@d&wv+JP(00X{kJ+&A0OHBF7*uhE~9kTYl z(0{xim!gZHg^A(XMvmhyEKQLG;`QHkXa9sfy}UWlgHO8Jr$$B2(?#0pe2UzniLWPBpiK zZA=B~Qzd1Y`d;3=Bg2uqR_t5cvh?b`fo1;Qn{x5ijG4t*IB)TyeQEciJ7Z-50_QKw z*qGPOm6T^3%qb#>YbZ6j{Q&rCdej zJ$roT{e#OtdNBK_{=wYx)T1ALJo`oC$3IDQ^vjLsanFqTlRh1nM$&TzODI(xU8YcrhQ8Q}fqopB_^Z5b~Xw?b!I zxp_;5gR_KUaeL_fW#yypU*dh?;fp4AD|EVy^gi{Dz0TaYwDaD<_|Uz>84eGdI?AeM z3!1QiVvkQyPbV56G>=uzeN8Nj-nc-IdP$>;tt*r^dlkm(OtlD(Wv@K5uSffmTbrX$ z{uuIx!HVZDV$iV71GVQj{lbLInTv<8K_xXdCM2-&rNEpH8hB$|BjeAPRnRl&*QAcH zKOZmowNiGp3?@eUwn3Bu)@;%jCPb9IHc$6A>PG?bB$}^s(u<6hrv0HhttDq(`oFPc zU$hjwH=n-uqIKim>-#PW8>bR&B0uh)gVEK-+C=@k_2t^cBFuW{Fn-{-FJ?e^JSec;{2 zAc)wZa9|>cZ5!Z76+>&{a;Jwb5v>aDZ))b!D0VGh4|nvZ&98KyIQAM7kEcyAt36A$ z$0Atpv^h92G>k1XQ=wfjteBFpn`Ru_1r<)wr`gg&y@q|%4cMe%ukaXcftj2cA4h#b zDQ&>68!Psbj7d|IX(RRxQzC2!mPk{aE@FEHX^Wqd+CDfvHl6hgw1<#1skDI@TXjNY z8cy4XC#Kn+K7vN^Ez0KQw2c)%I6NUrpHsbt z5s^0eKw=JZE=1sgWC6Go8JL+Rm;M^zB<>77hBMDSan&bXjk2q8{y4C#P&EJcs<+~H z-iq@!APR1-$&`tbPj-kD6}u;-MSN$0B9w^(_% z_D*fwy6jJSJ7jN1!rS$*;j!n?isw+$b6EBqo|1q^>eJ?1b=NG7Emu4| zmUJJK-3L*&t1RUyjaf2A_@21RmTd6@%fY0pOLhUJ=B%1mt+w}O|AV*ReLFUiwARSh znneAsgq6MUxucd1&pK&F`F< z?}-YlCd+##qp!Vl=DjoXXEFw}xq8)65*v$`E|(-7owB1d*OzZljbp(UYlFZMyMPk8 z?>A=7Q>h)|CxX2&+0)-MtP6VjG(>Cqvn}4^`?%i}d&u2adcp;JKg<=KXpmS?h7JD> z;EWy{0(xPB;-c@vt9=)YIX#_ z2op{^&-uZKMKtCSkZ8>^^5-{h-6qVsAlme8fr+erV;qb6aAb+r&`>{SWOhk<#gHI6 zB4$w_@wMoLxZN(gBG#+eFC!Mw9oQ40zz7>+=ZNtVFFGS8jkTLubc@aho}XjXKT<~? z+E*cOGc#{E&ArRpAe4Z>WBZ&fVt_y;KR8^(rf(}!XmZCj7$WzUpg1VV13^XyYS8A} zP*<+UX*@Ss23(-gpN9kaIz|jloMhy=?{kx;93G(a4kE(Fdfatodr`Kgy!E9mw2Dp$ zOT4qIuK=3sa0f|_M{wW-;gm6mfFY%woPzujh=$Bwh9)`!fm4%Lr>-!;GLx7vsG2W? z9cM9iX*3)N%}ld%GT1I}NIqC~J{HHdXbre-F^ZGq$1 zFp9%9sOD>9@KJPlbOu5jr8%0KA@rOXhnNM4pj*YJbvi7Apnm^xhSj7S7+XaWK+-|! zzk`!DojG>?Jj0I?O^IiQ?XO)(^VoU%TG}cF+36hZW+1iE;P|-oPbh~G=q_!+zSAiw zgw3YFv#?R3#SBC?a}lF63^WQPJ2o7a{v5&5Clm)`qiLM^fs*JZ{RKt5M-k>%=s1nE z>6KHj9AgzoG~p!DNl1T539RSNE1O}xF9&a2oEnnEQ?zGJnwiGt*lR;$;dZ-%5)+iA zow7Iq-3Es)hM=iN%KwGJQxtBea1kc_W8-N%Vf(?6@u5qhG(Rk*5g&p^jH3ZlE=4Zz zYsyW|Z9y!V*$wvcU@Lw3dFns*OWY-zF>kK0B zjoMT03PPwAQ2R!EW0spQL*^7c2D?g^Cw4mFs>L_nxLlcN*o`lXTN8>O3*{@&_Xx)$~&$TEt)8H3GSp7MifGuepI zwm~PB@|6<`Z(A*^k2fXDTII6Vm}w2!PP~8i*4ZUke%Hy)x&-@XY?RN#+3X9}_g%MK zH{HtK&8Od3IhX&Rm9!)rt%Pn}d55%fCQt@u*VCs@GnE!F#|E>l7zX?AAHQ|{=E;SV z(UT-DD5f$Xh6BCe%{vgLVK1!_VU!!9g<|TGC)yQi!n^)->yEy?+^_d~kJ*i%*?4l@ z{$owtXHE8FJB^?1;Nj}fCxKpuKJWZHpihy|sDX@)h!tIb=>Z#K1T1q_n6sGHrzM?k z0XP>Jz}FJ*LSYImIUd#k?!38HK@OYV_-7r`)*#_J009v}`9p=Pi3h$CE+ivtNw zq&~aWvrW2m9yQ%MgQm&tsPXT(%pA%TEkJSB*+1D3#f_;bEQi-{?owa~>=PaBG$a8D zf{pn1hq5{_W@*EAAuNGi*4a~`()>t>rf&{m;I80| zPbn=qD}*y{DLA9_+i^zfxopIm!}b2YTl-=Ml8zeLQ8V9{a)5v0%>iO_nw0&oFyL_q zKJ>w0z`ad&Z<{~4YV*gww-ip=nq*s3{8ib;z-a68&Xiz#-+Id$Gck?B$)u-Q_B1Dj z7FlRX2rUFxm6TLN>sRFbmK^rDsY9@Iqf{oV8GHPTY3u1yb^Lmwd`D8)DGNIj?E7@p z0l}t$fP2n??i9e?j7JptjX-RX5G%gvTyRF6s~a#s-x$9&$HRCAz2~s; zSBFi#y!BHPPp+-3x1Ren!1q;hpVr%ZJB*)hHIRQhPyP-g{J*Z;a?E6eO&vS>O9%f6 z5)wLJyp6M5HIaL{j3MvoXX510$IIbQD@gKU6>}i3Q{De}hW%G6jVY zqVCYFR;KfxQ3`UN(sVun50qvC=Y@3KXs%*T)C2+uuinZ@52lfFjT*9a0oD0<&{ z%Ne_n6e?w*GQqwXYc3ZP)DELO^~zy`um2^2?sA0(oq^dg>5hvs=lK}Xtcx+`jWC1e zpm~!+#4I?H${GYihC{dPq76q)38Fx$MLQ0Yvf)THCC(%|@eF3IppIO7HD~!CzxL3t z4UZqgiGM{X&&l4XCv7<?PBnI16s2buJ1&ZHvWrXs6qTS!qO&ttGo;^=?;AL| zjhh=p6>Qg(NaHu_RywDikzz!(p=QKj5*2Y}H82annINUO3F;XsFk;kNG7YQkMmBY+ z(MBcx?i^0jUt&?^@`Y)LxhG7Gbaam{!lcXejfm^2| z8;z)?WX`CQj}|Q7cT5puwuDmAL<)K=!?fj%Q|DjrK7;q)ck049a9rT&ARZLkjkE3$ zy=5F{vt5}BY2($g2^^aMwl8hCI@WGcUX99NDI67%A`DOFc7++Q1aC-xOri9;3N~`s z>6}BQ_*rlEE#-sU^qzhPx$^tKu)lfnP{LW8@-<`C+i3mUDx?Xq$M#-Igk=iMi;L zF>;=E>?n_h6`c+tVVx4kiU2m{i_uzj8w6A)8$(q+C5B3HJInJmVYaY#tH>NRQ#nmj76p`*Q~aH2F!8GXlv# zP;BSfYMHIsEWyFRkArh4i`G<{54O7$V)5Tn(X4!RS%T`En!ce}tNd>i{V&KNP9V(> zrY#EUW<)7WT#r*6qca)p$pGvp6!xzuJ&yFj2|7f|N&rP%h+aJ5Xu1@+zK!}bNCf+= zC%c^0kQ!Re4ai4kt@%?v*1RQm>+aMgy$!OrA!1SY|5DIwvv>mGP?olc%uFQzRRP^9qyxRUx*1$An7?T zd(LCCeR;(nS$=By1L2;a*t&P$dYev_YFhP|BuaNA{X1p<&d2`!EB^hTSQ7sIN&gAi ze*yyevSJA2%ZO6MR!#th+UVOv8hWt*%V;afJFCTkRgX7Oyff+9C3|)~_8eI89QdU4 zi=7G2fu!fG>^Y0Vd_^eCSG4BygUWQ3fXaNDF`^jULqt>jMOAlOubKPQZ11xeKXvcw z)6%|@(xIkIHK$&Z9xee!Y0Tb3Qj@X7#bCxdWe>lpiF|l>#jmb zLUi!PVsj`^xy!1k`+=Yz0Ve4%&6%O5EXh}r7iBT1`2%6&s#GAClJ13S+D-DRl7i>u742lfUpQ-Uilau|t!d8-l?fHa zCYx0YTh6vIsS0E1;NPa!NKQRN3Tf?|_T~D&zIMVg+H*IdRB`CvWOgoS%FC5jXty~h z{0(PAzSB~0Wb8Va>6sDSr7w}| zOCrr-$a%57OwnW8$3i%nJPh-F9B6s*2AvCIquY=q4dE97e4-Bf>hmSWZ#*aLev0>x~0-q zP5eN`(k@7y7&kz5*DmuZkN2+ijukDyDLh2lBa}rk2NEV%EhJ3ZuzYOZM|gUJRM5z{ z+zTgT7e45@cj9sNww3B_%NLT>yX5L!f7xiXOg0~qn-4v@vC@1p(R>o4`i-BOb1Ej@JhyNz%0AzCx#H58xYU>Q*2`W} zM?eYlYO194?i+XBxc$Aw@5Ky%$3udhjg?DHAC~-yEfLtIm}XF|#FK$+(zh>T=KQ61 z58OGh^aJIf(Z{}>Fjs!q@~A24J1YB*K5-Ul`}6eodUTJVnuajFf3>yb6r^ZeX>Wt^ z(^4n-8%(_|)=yiEmc=C4! z;Qykj4enpom!8^ZY&Z2|U)cYHsz7uv<0k!roPSKt9&$b+XBJM{dKL#IfT))qP|!(o z7=ca;JZ7>1WAML5Zb)kR@c zn8qo0n*C(NiCdvl?KhXikruaQSW)6u=xp0=u7(XS)QR^`$`!D1!SloVUv7Ey>c`)c zcO7TXn>xyX&{!N#8)u|(#<}2p^r>M;6Lqpr;*A*({t|pD{R`SxD|Qi$+9$}rOz)Xs zIHI9y^Sd@gbJkqrzY;B%crq4|N}wClq(zO{ODy0<5rp;mT zuu9Eg4a{Q{eH)Fz9L!c=vci!;%O&V6C;P;rZ+%DZ!jao-)J4yWrYw9nOv`87M9Ww} zGcoyuhPr}$0=t90&xzjioH`mB`Gxd57>(_lj7G6mQ>dZ0H>Up!W)vI2POSw|M zwtH(sZb>ZFw_6H8zf&9GL)Gl~6)%}xZEV)Iezsz^!K4;$S$@v7muKndI>JiKU>zRy zA~;Lb_}3TVFgR-%=O*|$p0yabYW-CxA7E=5``rpp#nbl-V-5%c5w&6ri$B_#nf%cV zMANfY5-uI=?EI4WejFR<1Y*D`>K)ko845~`)a>6-j6q^upaAWrth8$|TaqHBsw3ih z5M^|{M0jO9bfiOAK4+SB-Fj-WIvbmFM{;Ba^w+iyN=?)+}|sSC_*>dT*?gtRbx;}WyuMWNT8@g1|m zb@9@6>R-EI);byvPh;3-1@eU8Q+B!)D{@03R}|ItXXN__KkGuLUn&l%}rXwSZq?Z-a>*15_>(FSbx7(~t!FClmFY zNg1V1gl@#C(0>%LS0(L23X*??>VWj|VsZvguzbpxEN0&ayJJutm=3Y@*Cqlx zmUqLUuWu(~$NW{X15kt#3&*>fb36P_Bt1>CrzzoS%JtcxunM_HW71hIJF64U>Wsle zrxMrPJ$mP8yesKzlYMOoXWP?NcPR;JA^prbYjkvR3_GU~06qy^jU5I8u55#?8#VYt z!+q-?yZ>YNLt`?~B?r0^zCB8-Yhy2|t!~J*x-aRe$BxE?r~dD-nHj-t_Oc;0LgHNP zUu?bGd8aeJJ-!`{YUq+1x{}3vR?bN&z$8(*GwIkRJ9d!?Tgf9RsBoh_O1PzR z$By9qku_&2okz0Nt8#{@CAKrRla(L+QO1RWNtE1+wfHM*Td#@x)KuDAY5esO|1lr; zna_T#-uPL7hx@tRf1-~2yv}}NyYcgFJh?l&n@*K;e_8(0=_=ztt>odR4a1{4B`86A zMsxoZ9#Vorzr!$qRHU^x(9?x4C_<14YT{C`JMWoLwN?A&o?)d^h-oe3AhkISkt{DWcqy-A4vVhR7cG#H-3 ze+LXpz{}h}Ca`lFDFJq@w&)x0M&=`{MRm!ddby|`8|>F|fgkizMCr}T3zu;=O+MJD z3np`r^(F|^l1BW#CVE)ej4o!kb+axR`lTI+QMg7u>zH;*L)X|}hR}IQ(jgS}-%^ta zYb$$=>Chk{_fc3Z+QXxJxAb1wyN$s^?^be!;mck56Kdx8NvAG`%>YU_$AgyQ^>2i> zv57oP%v}*MwuQ0Eaj)95UkbOS5oZOezyQVdGoJf~>iRU^Zc1AwLRW|JS2Of)eAk9Y zu~S9yus4R6PW{9GT;Wfz6fqce4H7U#Wks3joKmS5WA$e=R^LN3ECas7!y1!xI`yl* z3Y35PT^lo5G@rqp_X-5!Q0_+ z@P+#RbY==KlpC5)+VZ90Nb~kD>rEPvQp2C*tvm};;+{@an^iyN z4qkJ9!y(|#zILx>2yHXGyeDAbBn>9yjY8`sXQlm z5p@JHnnk&Os{ASXmE%vb4ndO=)k=R#>1O}aq|lILq|eAl2);qB!(PM+Blw9i>{PRb zhq2yZD<-9l$ObYu2vB>C!r^1#whO)IyZc`2KGiS%6%{l@4pE=jFh?f;SkNTgR)pP7 zI?)X|Np~L79ht&lA9KE?+-7ICEWogN;TU`=%lrQq$ePI0#FZo zi|>}-DQ6qcda#PU{>6&N-ue}9y<#;F+Y!CEoDiCAnqaqw1vRxa>Ke@Em8U71edp(;#~q5}pPq zg=2?P{*t>V?wq)NYVlNzeV}so*T)W%HMzI^Z&em63Dm*UC+^aPIih?Sk*heMtO(da z7R*f3L&OIDMZNzR+`Z+!E!?k)y6NH5mhQ5?!^U49Hsawk&V9^h{H&OVt3xFgWM-&j z6fZ!(t4qJgpe*CHYU(_&qXXpif~`1}xbD)P8LFGc)CP9x!6yFt12f|z6)eyZVlcna zfF)fis@O|kid468s!jG!tuyu3s=78pc*8I$p^v_;ihyk+Q*%Zk82i5rpvO!j1><5O z0~9_D|0T^y_!DVPqIIrWt^^R3^)^U8qII&ElPxrbM51BOAx?%bnd3xoi0oN#^t`L$ z<_{NsNaq@sE=ix#GapS2zMCygJsC)@huw!TlslHONj?<>)s ztjehQ1Iq`Yd$Y;%Epj<_?1Nj;ERJ}w%CS6g2Jnt?Tyy)5#r{w&njpJyLU6w+tEDK3!Ee^XppLjO&1a#nmPB z-!-m1q5r11s)YWV;#v~=??!3Xx2LeK6jzhbe>ZC3`nn4HwPte7cfWTkI{Z%md;RnL zn$i5;zNq-_(fOk(ZwdB;dHnOI=1;A8Ysp_Te=1}7j+uwjXJa>3zu3Oiy}0cw7XMpq zs^j)19$UBJ#9qarrpCoV_OSda4%;-z+i{`>qP~EVDVI#+>*tT~9(I(<`FqeLl& z>=_&RIK6X*xAIlk+_i8rVzsC77Yk&TzOY)VQ?P1{A*Ol-xgl`^}s zEN2CVrl5pC3=P;NDTp4Dl=M(??Ww0;rLs`5CqpSTw+(Kgong22K z|NHH~d#}Ach@gGb`Rm-IgwP*s(r7UE+vfW)tRajrr=ywr$j$ID=XD`1&WIf1(R&CB zR}mHoy40{kcLjtVz+G=M66P+TnDmHEr(&Gjk<1ttS+ddzBQZy4a!b!2{8It9c?ZZE zB4~!g2=?TNa7k<^5-HMP;Vdtd2t*TESRp6%u!8G z8N_Y#Ibyg{K83A$SEj_uQDZ9EOc?CNf@3M$L>vp;0@`S{Xba1b7|h+};b3srTT!yn zrKTQz)8;V09ZFHQWsGd;>(;e4Tec;PcC0BjUvBzr_-3Qsb{D)qXzsuvTVZ>g1{p>d zkj z)En3pvYBiw;EE>EFH#xoXd5F6BkVD|K{K035=|!;EmzbNrsWFB91u!OlPN?S?a4}f zK9eT#Y$m6ZI5Cp6khKVon^q>d0AM|07K~(K7G(K+K91p$>zQnt7*>4VO6&32OlCow zBL<-fD?{Up#8`~$so8k8V9jTYiKFA=aWiF+BXAn#&5S4YRB|D%v9}=)KsuT&xZT=( z!oWJ5wh`#^U<=TWJ|kwanq?p>=${VMA6f4!@A`KC{R7p$!%pAfQg9>G>4c&lY70!% zdWOo!oSxCr`C7Pt^~!p1^@Vnc91E`ug9DT z2G1>a;8|;GF(3}VR3nd;gwIf(i*Zvi-t9;kDJzxGwR(VVx0#zY$>kgbyR{S(X&4Sk z_W*Ij86Cs=4wF8%_Kcay(!&r+cQHd1z(NySE|+(=Vxv{UDuMYGkiXzsK^ubyoWa*B z%AQ*Epc8$)q72p)wW92Gl)dYVRb`~k`fK|fWnX!;s*F_>#(JU{I8{@-OYg92W9WG4 zyrb@~jhtlTP{r^6dIB0g@s!|XMcwLV2+r|PJS(GLm0_GN2R-saWq*x7HVN`o>D{ZghrM zKf0bT!u7&>_*(Hsv7!u6 zhEVv7Dw<{_(nQnTpr)lW7%DIDs-|7eCG;%`2X*_y6sy~&MIm^@qPxMGvM1*%lUBXp z(kNSd703_B_wK(ilsz1uuq2s316gTa9^WNRY()0l=`Ra+_IeV`JQ?-$-Wpx+xpl~E zV{-+C`@8_-f~c#<3o%Yb!49vTacCzwh~!?64@#%XAcEok_>U)l!p@;n{%o5(7C`ap zm%ggEJ0uO31rNb+zdrc<^GH1|77`#xVXqPUaJaHn$fk@rdK3h1aO(#PK0SVh>KT{- z(RNmzD5vYWev7^V0`_v5Ngzz$1=wl}M K`#Dno5dQ;ajDbG@ 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..f0c04130334356cfb21bd7ec91df5f44e7960174 GIT binary patch literal 13380 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 K*k4pJ0RJ0LxrJ5$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/core.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8550a5d2252bd04303d82cee9e8071fe2203237d GIT binary patch literal 142609 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
  • eI6rkN-2 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 K9+HU7LH`Fjxe2lW literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/decorators.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/decorators.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4474e6f7d07a9f09a7640eebdf555b690ddd863 GIT binary patch literal 26382 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 U$Dz;nKMos1Z?Ke20i)gj2hN2;+yDRo 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..9bfce0eb4f286d16199bc92bf053e953dda7fe6a GIT binary patch literal 3400 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 ych!V2-$@ytcD|&z->i@n#-2Hr4*x%{aHg#Q 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..5956af1cf745d0aedd28d3f84e18751fe6116f12 GIT binary patch literal 24175 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

    )-Kw2k9zML(2XP!9 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 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..1d6cf5ee640f18ff1cd6a292134772a55793e428 GIT binary patch literal 26015 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/click/__pycache__/types.cpython-311.pyc b/venv/lib/python3.11/site-packages/click/__pycache__/types.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59bced0f75fd7dc7f4cd9316f17e070c6b9e099c GIT binary patch literal 53758 zcmeIb3vgT4nI?GgBtU=!NCJG5f+&&_Wr@_wwn)9-rmWDm9(GJ8MM4B9K_&_20+d9G zjOmPP0;km-+M}$Qj=asv*bd!R&nPL+w6-_B<7Cp^?%Cd2K#Llou&ZkI_IRtiXR4N3 zIXy1#Z1sNsf9?|iWhLF2N$u<4hzMxjXB4igJtZu!|xh& z!S9GT$K2!PgXQcmgWoggVZUq4J6t^ zkSc^!M;qTmjX%J@64u0FH3$n7g*9_n5Mi}NVJ#e1hp_shuvQLhKv-i@*cuLNLRfQA zSct<~5Y}20wwA-zAS@JJTTq8K4qJ<`wxY0g9JUT&?a{XAy7%m;J^q#2w{vI*LOYAT z?BKBV2-|=!I|{z+<2NqRk@`2X61hlr|z zL0iN+XpcHBIMolLWqMylT@l-E1VrqEZd06cQyd4yiFy#*$+61@y{6cX3l&=G9{o$* zhc8|HCFN47$HkLReHyju@kgzZa*R~J8&!)mM?A)O5z1T3FH)g@6{$3Z_zWSGubz`D z;>XCVig+Ux5em^#iyBIg*;0ivRDWTtYQ(Df6_l|C=>`BvJzU11+D-*!3?f#o(oVIA z`%AS>q;Av|sYjdCMJgjcu5p8sZ@rptq)~5A#BM^q4Usa;p_aTDsHdkVqv3yz5qL5> zDMu60iDV*_JRc1u@jetE4TVFK>XhgXJs%#6(Tq!k!V{6uNPOaAR7U)Z;jyV`qCA9a zRF04H_apJ~af&n+n?O2p=-KJy`S?UAHj#`g;j$bZNpe2j<^1jGcqm4*WgLY-z9UnK zBqfG|Yzif&&W? za7alBZ(?VslF`sOatfV|h7!?aH>W~h9m32;I;bfMok)f!Mz}q+wz(8bo(~NV55y;; z!^0v8Ihvf3CpZOa3pKDCC5R%4pctzzBjUFo5oRmA&p=3JYk&)zAQwX#tKN8;Q$T1}`A^p@#QYAqH% zJBFbWSBC<6jf)kEjdCXs504}-qjhK?3=i`_8XneC1vs9fzDBzs|AN*ULA%FCMyBM@ zrSs7VH3O>nB!<{zQcEQ^F*&6)-O;=^mKegwn~W!7fZ+r^^Nz3_OHSwQ)b#`TKy>2b z#jrdy7E2_D5|d*wEE#g%DSB>%Rtxna6v2l72WdEONl8Q4tn?n9KG5D=(0of8%B3bl z_lU(DKVkrybCy}lDqqS{LOm0Sk8p<~Mtnk<)HD>&BrpM$Aw3owdAVCzExVKPA-1d|M-Q7b`rcZj}0mf=Vw8tLl`?d;y7g~~N(Aep))U!kqc z1oY%uyz8>&%XwH1(GVA}9C)tCefDB9-tiZ^kgy`=>bF=c{zM8x;ZgDF+!84=hCH1J(1|e z=vaJ`=0eZ;}<~@1JUi>TetSm0N*?r=F}2BBh;)t zRP03ejlhZ*?C!7T3ik=I} zYvG~JC)93eXr@|kJ@ws}DEZoi&8YHQyWiZsxblgaNA5)q&?>k`@wfGy<`)Bmu*V zu?QAqEJNJ`?@RAnMdheo3Cd8dkcSXpCCQnfUMIur=Mnt@m1my+9<|WPXC`TCptYt$ zYq&ll zc~m!%z+{_gDX6YF_(e)+3pw0NG!E3OpqFN;mn>lyIt~zwa36+KV#zDD5NiwnL>zDx zErj(xHmboU0&>cFnb6k1&<1*~w2%nyGBgXL5{$4Y>$n*mD2ab<3WXD)OVP10+_lU( zV;X6zum1u$3(H;+yj*Sh67`Y2;NnnDF$T1A_i|83Ks0>}wCnh9k(8t)O$VJ!Tm`~#Igi`@dZpr!@tZJ6T#H*6atT-eiI=TIpsM5^b)ITOpZ@5xdA{M6UZzz zJ0pg`*ps2DNv#c-bV-b37KcX8Pffg>0AvRLfOrXjzG%8AfohOD;7>7<3EBsAg^FYv z28=Qy)exc#KzdL=3vyx;aNZck_;@rtq0CUc0NI809#jfpt%*%qxsdS$Q9)b~!n6T( zV@$djK0+3;a}#kn8tD#&o}o#5DV6|TrF^F)X8K+&APvbWhVK-e${7U)4l)KTjRfWr zwLolQWNZrPmp(M|gk3o}4Y>~8)}<^>JK#6L>}rk!#tdWTJo;vu^^sE?dYMvK0|$f1 zFICknxE9Xd@vXV-TeD=(hI%u;zO1h=?dlUlt4v)6%9Gs#ak0Xd#xV#FD8TeBv$k35 z4T~A8_=W{*^^T{aV?Y_vNg!;wQ3!M>kb`JOR3sKr;JXSm&<2!=Ks#s}bScP4ulAP0 z&2uSlr<7+Z^(LX`Z%{lU?t#8lO1`GWCzowEA5T~IW-5ELmAz?Kuc&@GdPXpzqH-0Y zo2p*0z?}oKgaz);@mjPK<_r(wxV~uhG4=SI zG$C5bP`#og^j7L4?#onEnQltKX*w&wpQogu@Lxa{5&EPKK7B|MyRTsIRhoJ@I#aI? zLvzS)(6vP>TzgD z4p2NxGVeM>?4IYta^4PVXe{p=8seo}AOVO-thKxiKsj#%3d9g5?^03Gy!|jp%DnBs z#I)Roi1K6P^pLZS99o_7u2a+n;OodlT*$lVo&5x0w!D{~8NpmfzP02q9Z60-{u9pv zx1Klrtyp~y*NQ|=o7DN({E3CN*ETMm&Q`aj?HlpS*f-`{TIY|XwqEU97`eJHZEwXd zV{ct?N}kI3{`vk_`vJ>(_oVIhi)*iMTzc-E!JD>shO&*1r|rA(%h-3X*lQd+7sJ;_ zmrgCOz0t8Wm~Gv%BH>-3vqjq2o$KgYahEx^uSjt2`TSR>Rvh%`l>Aj!XBHpJ`Z`z2 z=!HwF^j#fXbZ0Bt#0TY4x#wzd#iM@ADF~<9;`owfscA)``^~Bk8*d%@aE*8>;W`}- z?=m9ecB|^gjUOHQG2-H((5b9-1araKYiCw$!#5@xZ~KHGbTmJ@7m~ z-gB3uY!1X*k<88(mt)t`sTB#g<>zh;-m={o;)g<~QE!|+s#V{;ssJ@jUt!bq6*f)Z z3Yw;t8b*A`Ukj(&=cvxrG_Tm`-myj8_a5Lo6}dL;4`tnJR~!hZQBu<3>B8e|1Vc=_ zY>Mvz5j(n^fTRRbd&C-bfbVX5&Hf%j4bm8A#12^Q$X6c%>|}PBHg8YMG=xpeE}|4E zp9igQ%uAp--EUZAB77m*s2PYS`&D*rG;&0i$oKby2==8$omj3?YJ!dXTQNuYz)56S&UCc=}82=2cOq-B3;qDi>>g3EyLo_z{0>4HYqPTn!pN5B4mre9KvD0K?NvL=u`Av8ucr>wz zSQ0#%T2sNg)%P@X6O_)plxt|Y-jcFkb>{;0bW7ond(|`zXbSK&_zFDVu{>-dENS&X zRP8cP7VvhZ3tA0lLBY`a%3K8NfT)`d81fWGvsk65itpQa4&~h%XEg5yTXlyy0|JM-m?qcJR$k0I5(_sm2L z^5!VN$~z-bdSFyTrj9Y=T7qZ}nmbe>oc}q+{w^HQJWiLpix`f*Z}u*p$<(aN)~ri= z*L`-^*RUcv-CYL9YOCnITi>*J+mf!LIws+};JF29m;q&WW5{GhTlpB@v_{jI}%D|B2od{T&q;T@RYt2pHzN0)-)kk5eP(4zsx!J~rW zz_%iOp(ExiRc-|T+NG^b7xBuBGXTol_4OzM975MJh}aG5gu@i#G=!8HQ@}dm!a7lg z6~_fk#0|eYQjYb)lMkGkz*;>5hFMf7R*(z=(iLJ1uLfcSZepC%1ZWw~(B!A(L|G^v z&U$Jtm3Ox?nLa{FDyag5Smi>Q)`Eg;1&4kh?>RH@?8#>i9XWOC$YD`}lav_64)Jg! z(E*@>jAf~%WEs@pKceqwk;m%fYfjB^R}Q>iUN|FY0h4K3h{>Q0d@&iuDWHH=5t{7;Qb-FwJWN8IP^SV%2PG~kP_ zS$ol?QC{M8vmn`!t3vr{m zn66gWRld^~aDag%VJFH}h%f+13?Zn?l`oHhpDq+Q@{Y69V57=3>tq^_@>w`wAWSFn zK}e2B(+hsEHB~J!o@7|vLljwuS)KeDBITW<2~sIb&`=<*ydrNCOL<+v_)_7|pCNMM z-@yUz4)W95h3MO7GM;r=4<=KEyWwtid#1WGTiuyDv|=r<*rTq{r!w_j+4?Sh9d}ji z0eP!9cN?0s4cjseJF*Qs7M!`7hQ(8F?pfHgVzmViSaP9`A9%m-U4A|j+K~4p>;e`1{yFu53V!QSmj(EhC-Axu zo=(y`a{iRQDG5)j9F5BQPCf%XrAGri#iIgG;aic+PN&6DFW_lC!PAnCfTvU#8o%1* zR(ub-0g23{s8A-1)J9fSD2zBrNib3d5Y^} zJov5*B&-)GK!xGC0?(DK=BK3+DL1P2MGOjj5uYi=RHxQ}d=K5N{}qOA5ILiI2xF zg{Mj4L+S=fU7*|-I~Nn;e<~y@tdxmcLXMsb%Mla^Dhi_^D1?O*(IKcALZAzw+%V(= z&@P&orjX=i=%>64jaKNW>)ksKX`vK;r> z=J;eXF)VbJAmO_lCJvPnS7qm$O3)WNB}8wdkZ*HWjEB)?N);d)P8dZNTEV+RhlSD} zOBbM(r0B=xo#M;WP&eTMCGwT#Dk}^V<6?+TP--zSO>{PiRh~l} z`Rj1NG6|7idy$~jwWWy2ry1WNE{?_<`CGh9kXQ~VVO=X&BHmoxm`bwy-PhTdVwBYsI+aCP4ahIq=Wp@-jSTB)m}Za*4>a zqAOx8t$>LR(wg0j1m7r7%|xTy2WINf5OKf|(l6*McVAJOZEnW4sodRV;WkGHScZT! z^3DP|g|diY-3_0SxyfRxnMPyNnzfd&$4E+S!B=4I`TXgsO&Q>Gm!})#vOf8@Slk*IcuX(mi3$t2l3C zPbId^+L!EVIgNL7DyWkUb^2vH-}5v8LRn27e$e8psiUXmoSQkBctre-41 zJmTh@;8+?6J@tD@O4jIp+JTlNfrxUMQpbS#KpX#Ng@z>!tx~_FJJuoRtn)^hIqt0W z^#UbJ>_H>F0oQ&(F^J>G5_`M#I6;~cjYwo(N;e!9zvbr_JC{1OM*%&w zRzO^W9$d_W@X)Hp1#S8Y#{L{srZI-`zW6E}!?RXYs#&QNluZMrFd3{{Zy>3B1tB=m z$dCXKd6$YoF{3>}4TrT`S;F4L)1y=#B)F8=gUDFXz^7@g)SbTwJht$qrJYbltqR=n zZ@BH>u-uaIKbiGEd8>ZKW{O(eK3X@D6isQJMzwW7yyI>0Wu9r=HcfilxCkK{jgLjJ z%20dA-y!F}fs-J(qv0)&TJ;cBy$@eLtmdtE{GGS`of-dzEb70ZRJ}j9ZVJsbUSWK9 ztvp9+S)_!b!11~6nYN-Z1r63feK)GqPPL)2EC9Y&0QhTok$14h6yt32BE_HuAa5HF zPv-5!GZcaW8j^V%_MFMT1s|lKA>0a?4_;*qacT3FrV*8pe*<4Iaf`+r)*7@6Z)Yma z6A61#rNq;4Xxvmv^(`rHjwjE}+dvex!trS)3hzyw9S~}Bc$W4U)-Dabm5n)S-Z3;Tho*F_S~y&d@J^5 z>|NWthnL%LY|4b5%!Z!K)b7mI?o4@dF7LP9-*Vse26FyQIscBk{+flu*G^>oYqS2f z_si@RC?%Z#=#qTFZ;dWKzT9-{<4>SF(?h02`11d+`E4(FQ>5RMRou&7kI6HcrJ}I+c`@ zh2>bZ3vq@0DN#XYYYbs-e zbjyA?MeF=_ynJvJ&UY+NOBM`pto2R2vkC8tuh*^SVgAqSW-ZT4Z&@tT)n=W*wdBjW z-4oRA?~A1(ZyDj?sVo#?jr`oboA%0Fo|N~_Y*3(^SvAdoEvPY%(uCN7vVHbf(qCa# zq-&4kxA@%6s^4$^QS+?}nXUcVt^Ihl@HG)+bW2ZgZUsV-4XvH{GP{`^|Y=?cK0bujz_*2-b;_+ zo~b>atv#MPmO6H?VcngEuGa{)N+n&Wc z*LKlvmeXCqLc!(%l$dwT3F+q3^vG>@n0&;w5<>suILDs6X#UXt^d6z~d~3k{|Ityn8bb(5TsmUqgRx4+}# zhmQh$OFwsp?}d)bUP37V@6gDrI9`{djg%>IyII4xLMLExyl5d6O1j@d9J-fqo$U^6 z&|?is@)^Vr^k@)2;877jz_%iqof8&|qesXedMFd4;|w}>u!1AqNx_lsq~M4|o#nTE?GOEB!mRb(1v zEYomBNEYIPOoI#?RIs@Kja0^_eMn7^j#Djvw9=5TGeU9?U%@w&uNFVz*5k8$L=Q2V zK`4}a_>nHjJxJYxWFS>6$*2YnQ`$R>+nOYV{PBs=*tsbdK(L;^ws#T9ld3+m>;a_5 zv0rAxM0{d1Wj8}aRQM7S>k9RsdM32Wu>Pk>B(YJg)J8SprqJ}m z1t!?ROd=DZU|%3B!8RDPoMh9Z%Sj3vhMGjvc~N$94Qnmi4S0`TWN6}HeanKpNcD+%dknBeI^_*zkP1eC9R zztV~T&hd|suBrx0ej}HR7s{C`bw+3co+u#&YY`a~-v)qkdlvw{eTTszp-&2b0vOjL zstK{D8gZ?@0?)5Z-oqQ82Sg2R2C)uRb2W)hP^+v_rZYwr-iXhzwwKm+HOh1h+O8dx z6{(V#I@OLBTz$d#B3gF|uZk~FvB+6mW*ipeyN$_r`+)q95kdY2Ip2hX&Lq|kSG#Bv zGov{(0j-h-!OGVRo$A}Pu>Gx_Z|++jYyWoz1(&MY6z)NIezY)^Z) z3%yv2o75>32gN%u#lCyKv@$7@yDE7zcv$;&t_=w-$qHu z4Qe!MVB&-}q-F%5+<+HdHD5rXK1F%yWa_FEDvuE!9y*0uk}l=KlQTetIt&MEm-@G2 zttPsZoDI+sB)Zf=L>nBYOSj(WyE$@WUpBOh-xWHQzqpdR1r#q6o12Lq#Z#fmi1cqn_wd+&-$p{=BEM2S63$snGETHOiEH2FjEk4U{P!70MJoq9Bb!LprT88!!=vlOpOLU1N`t1xJyh^(1es2#={_i#@rEAWH>JgdM!oHV zniu53dVHwa8AHq(^@h9@je2*)4U(=L%i_S)_}QqeX(=Cs_$*&BG{JAh&LD$yh!7cl z{VG4uoArtVHn$L*SqrD&!Ga;i;f?}zC#tigeMiA(LGlaxYoy8XP$fK%=K}qzMXy<`=%AU*HNi3vB+lt74&ET6?jxY z1$-;gDvp2xR2&l&sK5)l9&AGSj4URy#wh+G^*o2Er}>IH40G6yIb1r#5p{wo12tOw zyCRlRFZRMXurG#oZ))%$YTA8SLYcN4j3*D6M#epwUSpmGwlfW-i5Qtil&gksjkfKn{)C*5$@x<_sw)3#;Rz}w&2M#v(;`39P*`z|%3h{X z{utt5di$k79cXG-uBMi6^ Ua>^~(h^O)t{&-}XNNo)!|1+fY4?=3MVp9+hR&P9m zWY!3I;n%tfekvPZu!7HOEeM?X`_79?9KsADbj0w}(SJCCj1p z;BWZFw!Uipbr1uY`U~6vX-t~4C$-j<3KZl@uaZP!7uu`?v1jO|h%{x1ud@>Qs10!OebKM2%9Rps3n$Y2`#$b!KQ-Rx0jm%pnKnkaK`7RIO0*S0F)u&TWFQ32ha<1H)id;Q^-(lTa z52R^peaeZH>zjX>?_84Ce-&mx9Pa&=oG%E1q+%b6@Ya<#uPp6&XXo;BH|-x*Wa{>2 z>-MJod+&)Dh-!#(@@C+}mQ3BgY~8-Jf8RY%6=Q!3&-2ZQ|Lx59d$a!DJO2H*{rhu` z%}a;xwC}v#zBAL_mu-iY6shXKBVdAl-6RjT!NsR0B6(XRCVyU)jCP;kZ6jkZZQT^w zy!ESjJFViTz5eJ2K{U{)2j>f}dchc$W#&H}jj;hH-q!+bTkIKu)Q5)@Z*ZX;Nd!T| z_#D||(|GVG1uR6FO~xt$1}>*CUB}+AJT1}|OnDknN=ziu7urg@Nj7gqHc%Xer67ok zC_60!D#&>Jq9O${d`%UG!VWg)U?;~W!&K9FOVIft`(_-(MbS$j6C3q?#gJDXe))eT z=PsNAa^c_N)l6N{kQWp09*uZ{w&3RYC0|=wRd%PwS1($9X^l~=5(Dn3A<{f7qw36C z*&4A7uy?ZUSXeCsrPtL377Ym6;&B3Q1KRm-1X zv*By8XJOV>R3d_dWiuNNv#CXr_-Nn`oH3F;(cpoxvB?naAMeHz<>7+Esvhqod4^VawzbSlY#^_YTgxq}EZq2g{a1HQkZ{`qeabzXw{ z#MPZ?PZM})*DKOhJqtApHOo6v2Xi$Y3v#-q1E6OoZuIkZ{9=&_RY_NFN{ysOmZ2BV zsEhF#Sj>jBZ|mYAIQT8CBPaRJW$~DHZ7s$w2{+&|a}gfW&C>e=y<|a8ThY@tBkodU z;aVFhwBrP;pVs?GQoGEnA9@($F5-9_y53mfW?TXoK*8k+d?Eh@oX;&G`7d!tClPWk zH+0wBeBUuJaP;WWuBt)~;X!1> z#Bkm*Iu;Kn<-_zs=L{aB$K&L*k;5x8K>@Cy&|Qhr<0za2O`iQ?ar_y*BZJoKb9l3^9`qehARCpa=+`+k5Q3+#Sj%-Eiii6%cg>^4}QARIZQcc~8n|$Tu z^N`OAHC&NIrBq(I;-hzzn89gwm(Xs(yA^3Qr?v&Au!K$u`3&SdJsQY)JSyZod@Isw z&R(d=EFNJEne>KTeE$flCV2a?cw3}A<8^FX0*?~6LZ{j4IBp?^BHbU|6)Xknl@a`F zmpV5dP#5crMPZ<8&;j=s8*ux<%SBJ&Z&j%Zg((A2IfRZ_z6 z86A%TCXFLvr!6ncbRkBDFhnBQrY^L?NkW&y{|*H_2~&$QHj`klX{ZmhX&4(u*%UpR za#%-K!U~3st*XMjax}td3ga`_WUFsCWn4HhtfX-yu?J8FVKbJz zEtb?S6zql1f`D=b*@PE3QCRF7)-aWBLPj`AW~3O>Ri8=I1jo`~uP-bZW3l9N^1%&> z$+)metD#H^FI2%{G&GFsV5|XSYsd@nwWQUJ&#>H`fTeN6x{O%-0qOv}N-ct(DK9aLzt{{Wfs=X^{JKqfx9Wz`mdnhNamgUtXnA;RTmDwK&N zI#Je9vHy+6D&b?r>~NaAJjDX=U~#m8SR`pJ2=f`dfePvd`ff8he-5Vrbs$(i<5P!P zx4`6TX{t3Lgh>~`R!Nh_`2q`x*RP~qjjK(+1C)_I2M^ODFBn_`efr&}0CF6Z*^BV# z({IJcEt3gyiC)RT8^$q z2YZ!AX^GSTpZquY`jLU2xzV{u4+ngoQmM(o zL1x8(ubKc~g8+PW0`S!l%q!`LmZh{zEn9&XbUj#rW8_h*Cqt>6YMirF1*wujrO=x@OD%dp1K_rgZaDnd<&* zb${C1Pg+xiH5a-9n3Y&`O`Ig^NA62nR`vDPsDV}}E+%v91M=sHkBzn7lT$brXk0Yk zsw;Apv2A$XJw+`OLK>v@LD~(9e$3CyVLLtDbSzW(RJQV|wCgERjlZVcyoI>2zBnI5 zxDbN!iowe?Q+>Qvmn7*vqff}e;gC||Z{abLbk+)5vdL+cybV~gT}3or1rsae8mT;f zYa;XbjiB?`D+oRI3QCW?g4AO#vZW4P#ceHf^jnDXqC1mbO=aC0|Ci$8idS+>Sz(vWQxYP!b5?0WJY_kZ3bvfuR7O zaex=@bs}_gNdq+aUc26dPnRc@mLZwrK&=o)p^+mfPNWNi!t4ikZ8fe<(ye7DMVw}! zSK64ttOZ5^P+lE4mXd6+!n13DY${1dPwypwp0{k}y*_!%G#GM_8&5|Qum=gAs~Wx~ zZyC*7Ci2#ac-|Ht9R*v3?D8C)S-Yxchtfse?_0Q+AmOFi2)nu<_$KAwg}*?g(d8&5 z!N3V|*p;84?qg7E5K;t9gF@BpI78F;EktK5-&?itrL<=)es^o?79DTwy0$CrZN29U zeEZ6`uDm{Xb?%O@?Y6Hi<7?0Q+EaEg1=BT8rakmyZB%{%o+ACAxVP~5J#~L_MY?ip z#=9-+-FC;@d)wRlkpohVjQ42Pd-P++$BFwkGaT0-I?uC5VJFxRKJ(0phwu|>&DB>K z3g=M&2edR1L=C1ca()9P4XFJcbpkmjsm+M4n%DlASFmFDYkFejGjNOO(ZDUjqrxqM zZ$&aY?G{I^z`1Jy;Tdcw`!wi0it|c@fZ=afqMScPJL-UN`PbGb z-K?aUXd5Y;sg6%isWKEOu;2 zkhIIHQQ#j24mhQsI1gA4dTl@TSl~VaD3WoW`NOn%8;cuCg+{NSrQ~Y*d>wKx4Tb^~ zOb(gQDgr}n7uTohppnl2hUn1%hVZC>A^7M-2cy&W$Y6*HV**1O>HlvLVkG@b9}9g! zn+tW}z2dlN1Jj@x#6KNS>@IzXGRXebLOiAr!+uAw4JyGla6s*?5^8V0 zNCje&w3sg(L+!p$r9PEVd-Fjxts2%FtMFYV_FIbMnf>^R_;P%q#5H)<%o`a~)D`qb zZMq*SZiae9f`*VnT@R_sBNO-a~zBubJ_4JI-Z-b*;mmRPCcSYwL8WIYJb z@Dz?qhR~bN8Jq@Z7N*F+e5GTHNt6n;3UT6F6r1~SWYQ(d}BuuVA@rX!yw zl5%_ur?QFD3Ar|ky-&S)W8*Lr6@w-nIur$)0%Kq4BHFjv{|uch&8N=M@zKPDKuPd5 z?X0D|xHe?@I06%#kTc+1L_R1BO${%n1SB~c#vyL{0g*iFN;NBXQ;G`knU8dQTz7~! z=2BzQ=oIHAa!n91hB6z52ljq)331{TnL!o92ZokmBNZpXC~+ZXq4UL|3ZftL#fC>o zih_zk{Es0`Y!zYx;Amprze?@E)kOo0!yYRVL)XyJ#e8(MQasUcdiPRWg)hdTtTKWo z&~!z(_#$;t;E8CIkG13Pk7{#38BJ zDG{Xsg-zI;BR-;8nt(t9tu}^Ty4+LLMx;(3__ET zaCr?mA#&D|(*{S?LtZVsv>tNBQM7=@?0bi>n8#3DAcuY_*Z}=vx2kPi+l(iVa@b8y zJQ3)yH`07_pyNRjh+{$C{V4xXva9$BpEcc3hAkcMX>`5Juk4ONy|$6jyXPdyhTWt1DaBskLE3xPD9Iv#veE@ z2{K!c6MN5dE52{l`5{I zzXpHc*U)$PRR*Yptxv!Vbwzt9gxg+ioV6_(QdLF^ZnFkc?dDp-D4RAUj6=zIFomwP zZF=if)7KH>*#c!|3{(4?eh}O;_GIJsruy!CPfLgR1 zQC}ONDX&wsMCB`pk{F6lK&b(=M81Y^IC2f>=vWMP)L^P4Z|#3ZsJGGRm5F-IW6uvo zhd$g?;(WgBnNuw35-bwhBEUugczNzBtx7I{)Yz!(qEdJTR;(1l66JGym_tjBflKRU z(4?r3e?$Q3+xQ-GFfRlui@}U%P1ZwaUn#tjPyAKaoawqJZv`{{eOdoLVwkkLpRw=; zy{_9eUCSMrnl0IyEvduzNMPiu=(!tgfovbjoxMwucgAm?{_v%b1Ao@EVzbs(Lz-4g zJMn6(7pxH71nL&{LI3GapyPI+W9e+Rb9W}NCmYz44($1)uKwD^x5L*X?{0nP@#`-y zZ_CtmXY0Dt{_am&yK?^ELh{=5Qu{lbp&j1z(dnPPgyh%2Y9<^czozo_XHo}Jvp8nM zUz2(zM~8XYs(Q7o-aWtkwHuc*olj;vpUebyW&=CZ{JW=?rDTMAHG$Mq*n~*@QnY~4 zRaism+5>O*pg|h9WE;2O0l%BieK;t5A3gr@x{P-q>m5j!`hg?#8OaQvq2ojN*yiPf z?!()ppKd#_54WFfD?jpt?Pt4tj%>C4(N+iiUu1xCBLPMeK6{(G9*-3SHRTVHJJ?w-FD*865|I@A6qg_Yy9Z)e)IlQCc9-;BX9Ah(cv zR5_Q}aKh*TDh_J`bsi&;r3= zHt%3uQQm=Mg&HuC91pQs*GLh``A1aWKZ3^~E=JX@O(ZZTr;n`zE6oaSHL1VNc2m|lO3 zgvr5=arho?g-&&s;~5JbXnbiQk#6q3Y5C9&P;}-)Pr7bb*0+1bLE)&5;h1B7V>;)U z-|#`lfmHZv^lHAhyum^{PJ;$cNsCg;b-Tw?6oLvnf0{yOCcK8^>JqS+$hKntTW~_D6EOG`h zU=9alv<;Bi>2M_PAeL7Yn8O+*%+iho<*Tf&Ti}<;`A;+w*CGJqlLrSpEp}!+YqKQu z-2Ltg%V%yL%XI9{cF<|ng3Lrr?W$3H55A6siW%F+69sh)c@TPP7c{IlYB;MF3|A|G z4xOp3`Xa5+d-Gx!wiirp?7_x=IsQHP_u{_-DXL6%3I0m8gz#&)q>lCKJ{aipj#fu} zU~c;(e#F+;+0k<2wW5e(=6 zcB(fp6S^r{&SlaV*O6xZ3&d_Ab~Q7g>(K9^y!}}~wD2;>3}PS-57Q$!E=i0*;`StB z<1w&V_I zMW*wURAw?SuZq4gWvOrh#RAJkA{AnM&nz+Qa2%(jFya&HvZ^ep(aW#^3tMzlBaRJT zpU|g{gTYH|Jm!ybH0Dea!%f|&rY-T{r*ZzQfSpu$X2gEP(N0vj;o;LzSJ3VEDS4^; z#I$rc8|G9K=NYWZDH-|6YRyS|J3-Aw_Wlwt$0jGqww?h&pc)LtUk*>hxZW77`-T*8 z02sB3Mz$$BDq0X*ulg#V(99?G@jm83^S-w*v;XL&C?|~tv^R0{3W`Snqv&Jx!2Z`peMg zKY;%HItD)KNqr0(()flH>d|Iu=d)5D$x_h!iui!~DMDr|!6>DC89{-pWo+8iDd_k3 zC0H>_pp0rKl9fg@FTJEpl)l`gu#7d)h*s7xWFra#9|RkC^`Q-CNm8QPyyD3fOLldK z&Lo6vg9i~EoYgn{b+N~R;xGY-$s5O!V-q-!i)STq?YWvf4NPUHmgVz+`a*}|6W}dl z^rNP1`kX$aaBcR8L};qgw9(2wJUoC#qPg;NG&&i2b~<@JKCvFsCvkL^R_O$K0hNOW zDpi6Q_sO`Hh(gd&$yGQ+d5^`;GQaKNTB}>NWQ-hUeVn1|4P0i9T#8k_vwMr45YI+B z>5Q6Tcvx$wJ*HwktXxkRlQV2~(8r6pT-2kCdmcRvmbZX&dA9~3@-B7u=UwU)q_dsG z^v-*YlOE{V7kx0=UsAJZRC#*f< z!XY!#kj@kXH*`p6i-Dmsq%p?8Btt30CAZ)S_=va?wMK(p` zVoLr^a)>~IwVn|93%=$LISKtk+D6Zb@%CaGP2v*F6QWpVDxSrh(j*J((B+A@@t#Sn zx)zotG_>JXsR|g(#!VWb(stFCYu-R7$Tj4Y#{hlkrv0xt?91V9Ben*6?zXfpUi|Kh z*I!H>zS^I{U#_C+>Q_l2r47615gDGl^$m-UeYf&@r5fiGyy*O{`?_0wAy8>Tphr+a z?V{nrL-r5g`7a^R!0^%s_oMK8E$?CYf1phPT>#=-y?1FufPYpX6j^mJ@Bn%V4U(Xy z38^+1+VC(_#eHuSlT3<#^a22X#nIA(vp_8(Nma$xn3xfVxDKS7%B`t zWF#Q?7R=vpjV2;dC@Mh8ivUPialj=%9;A3%@uB<}9FtV2dL$l&vcnKB9#~tTdN5PR zL#R051P!DsNDF`jr~dg_GW2_mH;>%f@#Ef1*O6@35fT;oYOYSdjUDZ4@Vi^raP7*{ z ze_c2y3OT~1r79EpvEqh4Ph2!wy}h8d)@<1Ym75`%dqDmw+Dwz3>7{~^A%mjPRCH_Ph@U7&SvX5AHH1J1#oHnF(irQ;MemIV{AWP+9DEOhD`6!1%Y0H%y!dUcmh zki#`cr2BA?w;vpQHfB)?XmsF0`5;?S6}V)G&ERGL{^R$}BQ3J2ljQ>g17Q`LYCzsu8|M zq+*_5AMQWNG$XX!_`Ht1{p8RyPcsFXx4%GMq9gP6FT;yX3?a&(og7AqI?1;K4$P1w zm{%naQgkbLsRZ#9Qc)2Fbm7g6S3&leEA%2^c;AKt49_c7)}*ZWV4|oyU44A%^gBbi z-KxHICEa^GRd&x;dtch;t_HT3^@TtOR_p;zSha>u+ghmnBv^OtrKP$bG=IN&`D|wG z*6iA?ch>gaUfY{lyDPhPS0=bS8{7@qy4_PzeHU?GSUma0OV?gnur63XyITW`(C!Kt zk5L`626qK=?5ZboO>6EnZM)sH?dG;j(-YaIC(;4s2m6q3x!-i(4FuD*yE1{@*}(2Q zfkU?ghjJ}zufO;^L%%(gY3a_kbpPR+kAs=sXR^J|VBc(zjqV0(A&U>zqWHl^$lhUe zm(1|Ofei(dQ-%VO_`6mL)L#Q#TUJs1ZseV@o7+C@%XIF|c8XWVl01Vi|V{L6WEsx?7I^;m?h;_c>>%8sjT#_@sjalEuv}tj3ghdu3oJmY^n>wi4$dm`<6f?0rF?xUwq zA3c5aC=@#E%F;&FAtYTsMWwGVxsjh&XyU=j`^h0(zoc@f9F%Eu&qFji>RWP+F#p!VM&Md< zEp54`P_Ab?+?8OH17|A3xd+=r4tj86Ay_FRpRfx+K4BJsd|t8yS3$l?ocFQfBOfW0 zuT+t*S_%XUjJB`TP(Xm9XnApl!s#n7VJr^sR;1OOdXFQR3qHPL!~LFn%ZdZ{70K*0 zK5cP4cF)(d;vf&IWYF;7Hzo}aegh4Utt%e(N=5FV)$hRG>*f_3-AS{9?xfj)yGgSH z&nwtz`~{9+M^gunU?6ChN;a|t#i;lojQJQ9AK=&6gYauo5ct(pB#lOs$XvVrr28Va zh#foV9AvZyHqz|6if`0wOv(7Qa_XTIiVE0&hp)V_SXcI%-OO$p^l_LUVX(AT5LN|M z3qv`fbYa(7CJ~RJd{hdJnPM_$Po>pr3blnw)S-se76KqOe0j%dI>Rqqhn46wgprCI z5mMRn;fpZX=vRfcyfKFMx+OxFNSO~? zamM4=UPaq?5}P0sCOd7se(-jpVeA*9-7d&NQ3)U-<+8FBYy@U*#U?B4ml=)95b$&M zh~#30mTx$Nb&X|lDVp4Pp-V8q@irXqonW|SAlCu z?`fG+^Wl`R*JssIhr|gO$~Lv5XvD%TJg6qhAV)|0hWQA^&6JTU-sGH>!X%<&u;Yum zK`Jhe9}FupUvc&#&IrVQLu?3Sxi?FT%ej2YI!kY$zY$i>62!(hdVvOkT4ssXqo&~k zVP{!%T(JQMs);^g*gs&}fkD`d4gU`|z#-h`H86P#&jE*oPn)=Gzrs3Tk}Ww9O1!@Z zn>Z0Zz_@D8e42alLB=?mlg%rT`5Hx>&7yT|ym$lYe5lNOmc*r2=V6ZV^Or6p~q(wys` zP!7Zp!M+a8;bR99&1@RTZW@4WZrkic*55?Lz&35c4u3=wbx=T;qEdXibyY3+wN3dT!?=|8SX@ez%fdT@wgbb>_09?&Y6}& z*_J~o_rm&&tI@F8sb~Ul*PcYOf$Z%Y5H!*|ATfo+9C5EI$mAxM&%HBFHK!>4xvRbnI=#UQ@<@Em6;aNWW+Tx^p|=< ze1=+&a#Ie7Z|Y4q^)6c%4_-e8Pr*-g*k2+xhDr)Io?kMxl2MhC7&|lNdba;F<*@}X zVN=?-Tb$=8QU(Hi0lrLAZx(J%Z?>j4?c1&VT#ACF*1AZ6dWHTUY=l#&9IE$&x!u)f zvWoNSczhL>nYjNm9#Lkf?q2o43FKz&FH<`}wH(428a73jQK(DjdSYu6zW9K@qR313qEGOG z&BxiyOy1Y6uhXUj)7KW$F^nl&$_jkR@tVtM)5JJ4PzRJ!-~agVnF2frwzT`MfUnAH z$ed8Z0;?1ng))v1hB1BUuaS-z$6?K`xzHu7xoma6duG=!{4LNJ<>M}E-lgW8cax9P z$C%fciKbag=q%4#fV!ksUmr5eecXT8PU(MTQVv{Nbt}+A z5J}e6W5nunfoF4p=W>CT`(<`wR>Jv@pamP=>|EM#Gq%u~sotNh-Va;i;AgJ*qzdqA zU1aM84()xa{CPm~2Mg-|FAmYt@zIgYj^o)K#}SwbJe`H>dphfTI_-K|v`?@k@qLgQ z>1lEfP!s%=d`wx>T5TY&kI`crIj6{Bk-<^&5m*vbIn&)ydK`tr;C8sn6j#K--e*qzRZCjbVal^3kixrTi6uG5N*whv&wP8 zq8MCfufcc?KO3yq(6eH`hP*4%qq+jZbF}mpPj$E!!ifwa%y*WLyc1LOq~Vq(NbV|;*raUtAi3NIiD=78jdRsVrHqJ}Kdv zXju8a*%WTY7p5F(b3~FhpD5Qu>rsGT|@UplhSUs&!?L zBrP1uRot#PjpV!9u{O*R06zhThsb1*MI*|eB_rggi6Yka6!1E$P`*sx5=pA;CjiNc z2QUvN)+g0HgIKN=6E$ECz;*`q#u9@-j*o}JDvyKHF=%NY6_(3R&ul-CBr7UJc7x*q zegHVxu#Q4IFv75rf}%!3nu@c?e8Y^js~d;i%BZ?LjnN~2pM2jVhx&;jrp$1dq3<-k zW0?DYlJ9TG`CD=hlT(ER^5xi(F?E)=iR3E}Bw#g!jDH*<8yxcgO|j0v0dtlY?kn_# z_uNzz@gj`GsGCUA5mP;_Med1o3dwyo&T)MXFE=-}F zd)M)9a&a!>*_`!2zqHZ~U?} z-#j%xJwJ`qkKcv8#0u@rU0-#ooSx3iUzxvxv{GJrIz2x#KXcbtlk(gvtD%Hy`Lh+f z%TcvrEpu1h^))QEy&cQ=He`JpP#FkDYumBTf83T1JS%=M*j7i|lItLuq*Fp|i1gXd zUC_WJqrW(DN_Fme{i(w%4m?6!i3r#+U7hhXXFbhndovq!`&n?q;l0w&_Ld*<*#4;8 z0#{I2PY6l(SE#p==)k-aBOI#nf|X9|fK2@=q}zlV<;!ru`#5ARGBG%17rlb|IdR!& zQ;%FuFC0^_?~`ERx7eUgyQK0Jr(b;b$k3sujvRWrf8bcYO5`+z^MIlgydwy#6j)5e zDF{)Spd2gw<^3iJ1o9Aa3m)Jk=;FaCpC{iWIakQ}Avtta_aHNiAvfFDHf4=3h=~PMd%Cr1fd@ zuhduVY031_Ug#{sFgD(Pst5UlmM$DfUF0nE->0{q>OouFmKH#r zB4@GpKE3@^52~-T;Hd0kXCZc<-hQeF?Kp3-z|?YSH}&Fu4*Ap={=Dt5#R7$h(r#+{ zK8Jj23?H!iEM&m2$f1(s?WcNB`zecsj76`0OV>SiUj%<@jx}a=SRmCYcG5NLsnLVf z=t=~CodpL{6gyB5UTUT`YN9q$qU>;30PTyNbg+xkt)q062>uNgvQ=H$O;@d5+Iyb^ zKQ%^q-coCUZG>Wnh5+7vst0WgQp{p!(M^K|F}0vA7cCa-6)x?j(C!rSsWDu}^xv~s zbsbFvPkJ4cM{qB6To7`)~XW_YP zgE)`g0ScL)K|VF!I`HEo*{uip`QsSh3Y`I~B2N+>Kdx zk|zyDn9kan)yC_45uqx`Oj_ufFoyEAw_N^{$3=S$(FgFK+|QvP3#v!|y3 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..e079fdc1c30e53920458a6c460ed1c7d4c868ac8 GIT binary patch literal 28086 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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..9153d15 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_compat.py @@ -0,0 +1,623 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +WIN = sys.platform.startswith("win") +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO[t.Any]) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, "os.PathLike[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/venv/lib/python3.11/site-packages/click/_termui_impl.py b/venv/lib/python3.11/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..ad9f8f6 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_termui_impl.py @@ -0,0 +1,788 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" + +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ +from io import StringIO +from shutil import which +from types import TracebackType + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + if _tempfilepager(generator, pager_cmd, color): + return + elif _pipepager(generator, pager_cmd, color): + return + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if (WIN or sys.platform.startswith("os2")) and _tempfilepager( + generator, "more", color + ): + return + if _pipepager(generator, "less", color): + return + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if _pipepager(generator, "more", color): + return + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> bool: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + + Returns True if the command was found, False otherwise and thus another + pager should be attempted. + """ + cmd_absolute = which(cmd) + if cmd_absolute is None: + return False + + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen( + [cmd_absolute], + shell=True, + stdin=subprocess.PIPE, + env=env, + errors="replace", + text=True, + ) + assert c.stdin is not None + try: + for text in generator: + if not color: + text = strip_ansi(text) + + c.stdin.write(text) + except (OSError, KeyboardInterrupt): + pass + else: + c.stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + return True + + +def _tempfilepager( + generator: t.Iterable[str], + cmd: str, + color: t.Optional[bool], +) -> bool: + """Page through text by invoking a program on a temporary file. + + Returns True if the command was found, False otherwise and thus another + pager should be attempted. + """ + # Which is necessary for Windows, it is also recommended in the Popen docs. + cmd_absolute = which(cmd) + if cmd_absolute is None: + return False + + import subprocess + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + subprocess.call([cmd_absolute, filename]) + except OSError: + # Command not found + pass + finally: + os.close(fd) + os.unlink(filename) + + return True + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if which(editor) is not None: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url) + args = ["explorer", f"/select,{url}"] + else: + args = ["start"] + if wait: + args.append("/WAIT") + args.append("") + args.append(url) + try: + return subprocess.call(args) + except OSError: + # Command not found + return 127 + elif CYGWIN: + if locate: + url = _unquote_file(url) + args = ["cygstart", os.path.dirname(url)] + else: + args = ["cygstart"] + if wait: + args.append("-w") + args.append(url) + try: + return subprocess.call(args) + except OSError: + # Command not found + return 127 + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import termios + import tty + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/venv/lib/python3.11/site-packages/click/_textwrap.py b/venv/lib/python3.11/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/venv/lib/python3.11/site-packages/click/_winconsole.py b/venv/lib/python3.11/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/venv/lib/python3.11/site-packages/click/core.py b/venv/lib/python3.11/site-packages/click/core.py new file mode 100644 index 0000000..e630501 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/core.py @@ -0,0 +1,3047 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .decorators import HelpOption + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Returns all declared parameters in the order they should be processed. + + The declared parameters are re-shuffled depending on the order in which + they were invoked, as well as the eagerness of each parameters. + + The invocation order takes precedence over the declaration order. I.e. the + order in which the user provided them to the CLI is respected. + + This behavior and its effect on callback evaluation is detailed at: + https://click.palletsprojects.com/en/stable/advanced/#callback-evaluation-order + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[t.Callable[[str], str]] = ( + token_normalize_func + ) + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional[Context] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + @t.overload + def invoke( + __self, + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: ... + + @t.overload + def invoke( + __self, + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: ... + + def invoke( + __self, + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward(__self, __cmd: "Command", *args: t.Any, **kwargs: t.Any) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.MutableMapping[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, # type: ignore[arg-type] + info_name=info_name, + parent=parent, + **extra, + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invocable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List[CompletionItem] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt) as e: + echo(file=sys.stderr) + raise Abort() from e + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List[Parameter] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self._help_option: t.Optional[HelpOption] = None + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object. + + Unless ``add_help_option`` is ``False``. + + .. versionchanged:: 8.1.8 + The help option is now cached to avoid creating it multiple times. + """ + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + # Cache the help option object in private _help_option attribute to + # avoid creating it multiple times. Not doing this will break the + # callback odering by iter_params_for_processing(), which relies on + # object comparison. + if self._help_option is None: + # Avoid circular import. + from .decorators import HelpOption + + self._help_option = HelpOption(help_options) + + return self._help_option + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List[CompletionItem] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv # type: ignore[return-value] + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.MutableMapping[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The latter is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator[t.Any]: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError( + f"Could not determine name for option with declarations {decls!r}" + ) + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if default_value else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + elif default_value == "": + default_string = '""' + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return t.cast(Option, param).flag_value + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the constructor of :class:`Parameter`. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Argument is marked as exposed, but does not have a name.") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/venv/lib/python3.11/site-packages/click/decorators.py b/venv/lib/python3.11/site-packages/click/decorators.py new file mode 100644 index 0000000..bcf8906 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/decorators.py @@ -0,0 +1,562 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + return decorator + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + message % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +class HelpOption(Option): + """Pre-configured ``--help`` option which immediately prints the help page + and exits the program. + """ + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + **kwargs: t.Any, + ) -> None: + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs.setdefault("callback", self.show_help) + + super().__init__(param_decls, **kwargs) + + @staticmethod + def show_help(ctx: Context, param: Parameter, value: bool) -> None: + """Callback that print the help page on ```` and exits.""" + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Decorator for the pre-configured ``--help`` option defined above. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + kwargs.setdefault("cls", HelpOption) + return option(*param_decls, **kwargs) diff --git a/venv/lib/python3.11/site-packages/click/exceptions.py b/venv/lib/python3.11/site-packages/click/exceptions.py new file mode 100644 index 0000000..0b83151 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/exceptions.py @@ -0,0 +1,296 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .globals import resolve_color_default +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]], +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + # The context will be removed by the time we print the message, so cache + # the color settings here to be used later on (in `show`) + self.show_color: t.Optional[bool] = resolve_color_default() + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=self.show_color, + ) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd: t.Optional[Command] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename: str = format_filename(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code: int = code diff --git a/venv/lib/python3.11/site-packages/click/formatting.py b/venv/lib/python3.11/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/venv/lib/python3.11/site-packages/click/globals.py b/venv/lib/python3.11/site-packages/click/globals.py new file mode 100644 index 0000000..191e712 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/globals.py @@ -0,0 +1,67 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/venv/lib/python3.11/site-packages/click/parser.py b/venv/lib/python3.11/site-packages/click/parser.py new file mode 100644 index 0000000..600b843 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/parser.py @@ -0,0 +1,531 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" + +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes: t.Set[str] = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: t.Any, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List[CoreParameter] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args: bool = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options: bool = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we recombine the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/venv/lib/python3.11/site-packages/click/py.typed b/venv/lib/python3.11/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/click/shell_completion.py b/venv/lib/python3.11/site-packages/click/shell_completion.py new file mode 100644 index 0000000..07d0f09 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/shell_completion.py @@ -0,0 +1,603 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + @staticmethod + def _check_version() -> None: + import shutil + import subprocess + + bash_exe = shutil.which("bash") + + if bash_exe is None: + match = None + else: + output = subprocess.run( + [bash_exe, "--norc", "-c", 'echo "${BASH_VERSION}"'], + stdout=subprocess.PIPE, + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + return cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + # Will be None if expose_value is False. + value = ctx.params.get(param.name) + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + sub_ctx = ctx + + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/venv/lib/python3.11/site-packages/click/termui.py b/venv/lib/python3.11/site-packages/click/termui.py new file mode 100644 index 0000000..c084f19 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/venv/lib/python3.11/site-packages/click/testing.py b/venv/lib/python3.11/site-packages/click/testing.py new file mode 100644 index 0000000..772b215 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/testing.py @@ -0,0 +1,483 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import _compat +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(input) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env: t.Mapping[str, t.Optional[str]] = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + old__compat_should_strip_ansi = _compat.should_strip_ansi + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + _compat.should_strip_ansi = should_strip_ansi + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + _compat.should_strip_ansi = old__compat_should_strip_ansi + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: + pass diff --git a/venv/lib/python3.11/site-packages/click/types.py b/venv/lib/python3.11/site-packages/click/types.py new file mode 100644 index 0000000..a70fd58 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/types.py @@ -0,0 +1,1093 @@ +import os +import stat +import sys +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import format_filename +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name: str = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = sys.getfilesystemencoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type[t.Any]] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Files can also be opened atomically in which case all writes go into a + separate file in the same folder and upon completion the file will + be moved over to the original location. This is useful if a file + regularly read by other users is modified. + + See :ref:`file-args` for more information. + + .. versionchanged:: 2.0 + Added the ``atomic`` parameter. + """ + + name = "filename" + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name: str = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} {filename!r} is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/venv/lib/python3.11/site-packages/click/utils.py b/venv/lib/python3.11/site-packages/click/utils.py new file mode 100644 index 0000000..836c6f2 --- /dev/null +++ b/venv/lib/python3.11/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO[t.Any]: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file, color) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO[t.Any]: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name or Path of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict"``. This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return filename + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no effect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO[t.Any]) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/venv/lib/python3.11/site-packages/distutils-precedence.pth b/venv/lib/python3.11/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..7f009fe --- /dev/null +++ b/venv/lib/python3.11/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'local') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/LICENSE.rst b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/LICENSE.rst @@ -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.0.2.dist-info/METADATA b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/METADATA new file mode 100644 index 0000000..71551b9 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 3.0.2 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +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 +Requires-Dist: Werkzeug>=3.0.0 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.1.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.6.2 +Requires-Dist: importlib-metadata>=3.6.0; 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: Issue Tracker, https://github.com/pallets/flask/issues/ +Project-URL: Source Code, 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/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Flask + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + # save this as app.py + from flask import Flask + + app = Flask(__name__) + + @app.route("/") + def hello(): + return "Hello, World!" + +.. code-block:: text + + $ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Contributing +------------ + +For guidance on setting up a development environment and how to make a +contribution to Flask, see the `contributing guidelines`_. + +.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst + + +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 + + +Links +----- + +- Documentation: https://flask.palletsprojects.com/ +- Changes: https://flask.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Flask/ +- Source Code: https://github.com/pallets/flask/ +- Issue Tracker: https://github.com/pallets/flask/issues/ +- Chat: https://discord.gg/pallets + diff --git a/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/RECORD b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/RECORD new file mode 100644 index 0000000..63d7132 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=T3-0IsDKcH2MqBoWV49FAVLe8Ty-_2AE0g7ByuQ7b40,284 +flask-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.0.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.0.2.dist-info/METADATA,sha256=5SsBudAoun3E_3ZSRXJLB2V3NAdALovsQMKUvzqcJfM,3588 +flask-3.0.2.dist-info/RECORD,, +flask-3.0.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.0.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +flask-3.0.2.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=TQfhvSlv1QpaPHeeRz_Ke7JmiSFMMHT-rJR4tqsEHdc,59706 +flask/blueprints.py,sha256=H7u4HzNn--riGMTt5GkxUHpYRzCav-WDGSKNnBSEMcU,3160 +flask/cli.py,sha256=eegT_64cSOqaKOwI_Am3XwaCSJPZ9UEJ6EmSL0qg8xg,35833 +flask/config.py,sha256=QiL9KkQT8RWc0HU2AE26Yw5mdOkNsKv8TEFEbXkqhJk,13328 +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=tYrcQ_73GuSZVEgwFr-eMmV69UriFQDBmt8wZJIAqvg,23084 +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=q6iB83lSiopy80DZPrU-9mGcWwrD0mvLjiv9fHrRZgc,7646 +flask/json/tag.py,sha256=aXslvQyO4QpxviWJqxhyOj0CCQKlYXq1r0H9DKqiEY8,9280 +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=ZF0Yy610NKSpdJ1d6qtG4L2RkCmzngu0G9FFXZf4O_M,38209 +flask/sansio/blueprints.py,sha256=Tqe-7EkZ-tbWchm8iDoCfD848f0_3nLv6NNjeIPvHwM,24637 +flask/sansio/scaffold.py,sha256=9SSSC6A_zzXhcEVYf9wkrKx2r4uDqfIWsnRNYSvDclU,30879 +flask/sessions.py,sha256=bIpZRwiTfnYJn3ikVnCPcF2kNtyRz0dfpsuMADIpSJc,14518 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=2TcXLT85Asflm2W9WOSFxKCmYn5e49w_Jkg9-NaaJWo,7537 +flask/testing.py,sha256=3BFXb3bP7R5r-XLBuobhczbxDu8-1LWRzYuhbr-lwaE,10163 +flask/typing.py,sha256=ZavK-wV28Yv8CQB7u73qZp_jLalpbWdrXS37QR1ftN0,3190 +flask/views.py,sha256=B66bTvYBBcHMYk4dA1ScZD0oTRTBl0I5smp1lRm9riI,6939 +flask/wrappers.py,sha256=m1j5tIJxIu8_sPPgTAB_G4TTh52Q-HoDuw_qHV5J59g,5831 diff --git a/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/REQUESTED b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/WHEEL b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask-3.0.2.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/flask-3.0.2.dist-info/entry_points.txt b/venv/lib/python3.11/site-packages/flask-3.0.2.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask-3.0.2.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..ea915cc5e77bbaecbb6bae8edaa5f6b25516a4e6 GIT binary patch literal 3222 zcmZ{mOK%*<5rBL4HT%$V`F@KWKBVPR(vB!OHuA6)MNyJVbdX{g=*wVsr+0VEdAX;T z6axtff*cHAa?n9J`sBoM{ztB3LqG;|5)k;H8x18n=#o@5cSH`C9@f@=U0u^%U0vPF zztrnh0?)I?Kl*op{)LV7$(?}m`o9Vx&xu7W#UZXj6$LrxRlk}o+^?lhg2TnC<^ zGmH>0K7)mBrgK5({;&9z#7#gFFQqdgKkJ(aW>s8x+QrPc$;oZz6^YYUXi>8e3f36 zybj!?P01SY4&9Nw0oWD|1mlJn*rCDMCqouu|7zC{j*RY* zbLNTEZghQ5u*cZn7?`192EiHA44OtGoH5tZLBJbcRB%r9bRsomVF-bPwP<#Hj)NC_ z5b^+Ew$Fqi8_Y6Xa5VcY1p7SN1#<((6wEM%;C5#y81&R#bDu#JVF0;6Lzy$n=B$h3 zRzl`kM$dMzW9Fp6eb+c~@cEH63(ic}IJCv!%qr9&cZ{CT!9&Hw+C6lhf;EkDVg!B= zFzdW=7!IUy;f$wXChS7ru>3<@_I!uIz!1wC_p|1|gPahCsj1Y3~;hr{tFmdTXV46Q? zI(1ebzOA(K!_j6X1ASG+>_krqkA%a`Q+Qmi_)pZD*V0p1&sI=d`=#PJW)O_q^-|!#<9mL zeF0H@^)|9cMAT26o{((sAC#8*AgLL~0pnQhhQTqi-#+`zfN9M$=BDN z3q@{ere|q~w&Q3Wrg7%_2Vk>3O`dM;c6+a_eHb#W$4p2ZgBJzVJj|r|Tx;5H04K|_ zJ8hQ<(=vtG9tE?boU*0z?_p4x!+Qg>G7eG@}bE+ zD1tC4ASKg3A4Lt*e{|B7l+%e5bu@D_aW_4;_c@1?mFL%C;-vC+2L3LzL);Zj)870} zANVfQ1Api+oq1h;6hK<^Q25<_xE5}NM_$+LK;Plvp>AQ+e&E98r4NMb=pEnRH~P$D z+!Q|7514nLLq7E2NDO=r(zmCFwqQ2`STbHRx=f317;u_|VYGuI+&#E0)K7gp& z7#;`pdlIX)PoI9Hu14x=T;7OMiOUP0Ht_FddGb&7&+5myT>YoYe@djj9xp5&*GOgl zJ5s7t|BdQcstGc=^rErx&qnK;M(eN5uN${sG;T%ZTi;d}|2+G3b?rrUEh?u7y9sTxLah-CnQV)~MjI0|5c5=A70V>u^zxQ{pe-=WnN@uvy z;HQC?rC(P(<`p20|BLV%s!Q0R_8q@tIw8lZ=M$(Js3v9SfH?tFI-f$*G^!a?v#91! z&7)dCwTNm7)iSCTP>CAaeGdm;Mbl+eYpB*yX{a_(ZKB#jwTYdQ<+1>swG~AMgjz#4{fL4^G8#UQv{oY(`mm zNv5MzUXtY~D=}G*vJ#Val$DrlM_Gx<52LKaWczzU-jKt(uQC8xt1NdL$vlEew#AG+h%5iBzSwAM< IqvQekKLO3RA^-pY literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/flask/__pycache__/__main__.cpython-311.pyc b/venv/lib/python3.11/site-packages/flask/__pycache__/__main__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8a815914064b8e7c090012c3d784e44284b172a GIT binary patch literal 311 zcmY*Uy-LJD5S~p!IE2H>)>63QZa8ekN3gN82}yQLLiUf{H6fKJ_y!iffg(PLt)*Ng zSlJ2JUFGKR3TFmp=9`b1Z=R>q0|@qT_*NZ<{53Xvi~fquNhltH17`vxyJ8F?Aodi{ z*F6^)@aPg|@iz<5jI9%yH|k;*t>aQOHV)tmY)1C>7HcgDjlL0tq)Iy&PaK`sWt&$t zcY`YPBFy@}M@}6HZ6qm=wU+`5t=p_3MK<@^Vn?b&(G+L~Uu$)`ST4~up5`XsZF6`n za@S&(je4?dVTSGGOllsEpW8{$GwOBYhd(i6>;sP8|HmgJtK=@dPggs)X`ucBw>ned 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..a7dd8dfb7e7babb188dae109dec677519bbfcb43 GIT binary patch literal 63747 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/flask/__pycache__/blueprints.cpython-311.pyc b/venv/lib/python3.11/site-packages/flask/__pycache__/blueprints.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9257fbf13ae59e7d2890936e6c93b177cbda379f GIT binary patch literal 4341 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 F_!mqmj)(vN literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/flask/__pycache__/cli.cpython-311.pyc b/venv/lib/python3.11/site-packages/flask/__pycache__/cli.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cd1b851e1dca8671a2c7a9d8a09c26adb45c1dc GIT binary patch literal 46926 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 z

    3<5F}|_gK|WE{o@ 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 z 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 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..cfc64b9bdc7034c2c1d92153a51254e0e57af182 GIT binary patch literal 10263 zcmb7KTWlLwdY<77#ohTUFk?jN$0eal^qFJ(mm~FWhvoFdZ)cSrwa3( z^`SHmS~wG3$?oZHhUH51BzvcOdCtb2;uQA{PVuOHs_zStVVqU zR_kZAU8wCwoq(43ueBUhb}0Qf#OW={PGt+8Ta{gkjOUPIo8kf^e<71VNTUlc>y_+GGslSROK1fFjP%esfDbm znY3oaQ?qg`t+`~RY@=%wS>H17X5y)cwkRtRBNAk2=K`WBg~O>xQVoYqS2&zZE7=5< zJ>l?s*+`;R;|Pb9bTl0Pl6yjnTKi3C4wDFF(m)QWsi?M?!74(!k&a%C%&G_U#Z)vh zgSv%CxRjvhSef0({ z2W7)oB>u@xz_x>OD-vi*R6L3kPrKs6!FkQzlQfgbctX|BsEgL2-KiZ~OiL$m9*nGl zF+!1*EGTJKX49WVDJaVq=Tteas1Z4?%f?*9kmH6NjilI_WVG}()X9<7Gft|yj;$s1 zlsuo+4Ir>Rj7R1AEJCkGlo~Bs=W9A@Q_H$JdJ-u4B)f7Pg45)?jf`^2W$(6+X@9EW$|o_&^I z67z!gk|M4)kJ;!@vEShG!b$E6eEF*JwXJ`9UR-U6kOmS8N=M%Q33sn;J`hKa%}2|N ztv%F zfH-&$#6mneCnwcNszybrv^A}0I%R;{AUH^F7#a|gamWh=;}XhsjD|5R;jxGX>T}>^ zMXr+`IGX15>dsAu-AOA(8;xe24CZY6|6Af{f`<8g42`kUH z?)*F4T_~lSKHBv!c@oqjWSaJ+&9ns%n*4R0=t!0|A0BJYF{1nH8Erfl+{lT+a5$cd z8{u$pERl{z68d_BSv&i)lFe08#C=}M4gm91V0knB@*k_ zKIDdeWRr%`O8**QnXCA>-_C#Q-}k`3@BWFB|6tjFu;8hRcJC|qPgFTP7G(oM#XpoShZl;N3TW_hxN_^LUoFjgi!; zCsf(9zbfEa!usU>Vnk934nd->brTp(8cC(F3@2e z4vANGLfRH8Z6z=S5U^Qg`U+gKm$WVdG*68bmlh&$hyYm%mXabm*9PiCUg|I7_W5P@Jx#Z?m9nhC-G?d zCqa%UA&lNiXUYDk8&bK4jQ-W@Q8hz?kR+PcuxgkllwoQ>3C84ztXYjALoG9mslf#% zk)n~TPC9R$`yhoCEuCTCAU@~P5RkBJ(#m3u>E;**=~gFmY6=39VPOg+e@{(Z+%LZ| zar`7TJAdKgo9E9>$&nPqI|k8VDrR+=Y%!WL@L4xU4!%U#M-IMhsnw=4Z=7_rq3W=G z4JEn^I=jQSs?jBzQQK?U`@GE%>1m}e(92hio^;!3?tLEWl%H?3_ym@F-ZtN8gLg}@ z3czZpFMJj6wcxFifY^`}d#fN;I*3xObd}9R>(2|Tj{3Ler{ZXB%R_ZP1ygFrG>G(T zsa4sp5|?dAigT6SbJ{ENLTk^hZ&3ZD#$D%f{^NBGZ3$&)N7Cneaxd-K&s21s2IIP( zg{}ut)`*eNh%{iHrC~`&67t(`okc_2p5PiETH{~SXq$4&Oruj334KM4#Z%~JA#Ti} zFKCK*f^0w?hU{EWo+Nt~m5IcLVOS5FwIWu5l}No?R!FUT@Qw@{E|~jFo`T}2FB2BQ zCiC7;WK0~jPSMQxsIR`hXehArShTi)iwO3|Qhd;7G-Jknq=stu2@Q$$(Ao;Zp|`gZ_7 zKnHa8mpk_qgoj;QR(9R{>rz*!+!ZQHwOkc>?{R*0_Oq*y!6;d5erNIZ%;7ae``~S|r z+V}h6Plrp=vt{YoVm&h@@uj$#r27#)W_oLz990vEa2PuGHQF^&w#Tf!hH1!Y1P)Wh zDFAF|{jX{h>DETT({JBX<$eONv>NN4nM+I~uS;i|LOs#(L!RCg4*>&=jD=n7^ z5Fm_2+=r9l@RcjX)=ZN^tSG7;)#6aF*Hp`vXUZxvLn7hImAVnXi4A|{O3=k{N5M*w z#(i~^$*|hsG*E`-W2wARXwe8R2=QwXLmg#}qxJoyXKjs^^>Bx8u^&1LT!D|-aJlnL z3(R^Dv0leoFk%>y=v=rq(=fY_gxP!*T%gtsc*uZgLT|IL*6c>`cxrKj-tD84eSj(5 zvEAjIT=TV~P17{?zj-0;SCc7j7uT$zM>y?eI{6R8b)9^T*ZB82qe*jpAfg}8!@4eC zC92zypvfD0xm9;5-1|0#TeAI?ZGm6lt_#297I@2$b!e}mAJg4L7p7Eq0cg8X$4p1F zleAA5x+kj6z>`9}*?0kO)}$o6R`4ogRL1Rf>9|~zj>Mz6(Vuoy%`|%n?e#?fFnZM{ zd50hRhd*Apz3{Dn?*sqd`$tOtP}v_Uc87j=*f&(=I=sW{pwc(6GW%(w*tZwC;@k4w zz;pNg-|Q+4yjUK1@!Nrk2LlroU;pj%j|H2*_j?ZDk$To=+()A2j4+yPUR)<>ek^Uy$E}j3bsi_V%Xi6#YDrdBy(O<8FOH71A&GzFCHJ!it^E{6| zvfr~=Yo`{Mop9uJ!^m4={;(?AE4%B8aP@UIC?*FC%3xe z^Qn?QQ1%D#p)E6JSmQ@?qAVYfbGA`A&}E9`gtOcQ#O-E>4llo|kZXtZBfRu>G7EIm z1+!T*bdvXM4W`}5W)i9?G8dB&NhH{+OaT!M2ocQRFhzLb6A*wG(6i-RvR{iJ>|u(m zPoj4+ku7IZ&xVC-3J|X1U*7|Ew3b?NP24%TGVt-)+h@zZeMQ#<^4H2YFMgT$r$jk; z!un7YC#?K%V0h)7Ps87CJN#hV;nKF}%iEqW4ZKhuc%jO9>^m9w08XXC+ZA``N8=xk zuk0$hx0l`9VKzJaD<0oNcmFN*p8EO4mCGgfzOs8?m6M$P5BmnJt^MW&JWB&d%Yc1H z%Y8@5+}={@9<1~a-U`rP;XM6S2Deeo2m`mo%D}Fbi?@=ulEv;_jZCBU46RIje&XxC zuhoCKSll&Q>UpKy1DBXJmr9SX*tr9F#cn-|(vC*1ZmF-w5_tj~6dKtIri9Z&hzBB% zZr!E?IgJm7zIK@o?h-r1OY0G<{qj^T=(Jz9>L4Wd!)c+(d6^vf_#8Ze)27hNrAwD_ zbHf>5u2nXkms|Y(WPU(f@K62$5J5sX8_0KmPk^spP=qB>5tr-+km^a>+5EOHWY>ND zzwY^S80fKCytaAlA$rL(c}zhWoyl?*z?l5Q3bJLTXLmd zZfj5cR7-8`eGq!mJSiKNuosS&{y0UtXGf1+1`N%5%C|W_Vy zaeX2x?z{`)wN3Q%oIw|uTFSRMS+F--m)uY5UGe1In?*ow4&|N8g5q8Br23T3yi;+m zyLmFa(uGw@_k<-+Uc~GWSEDG+=JQv&^PWvdFqNJqFWL(=x6$BJd+2Rdk8slTEqPPh zXzZ&@&1(Lqw)Jh+HgEs+MBb~NcxtPD#D#3iz{Z_^Y72k+I8VhK+%h1?ncKsnrsxcwwZ@F1%;if? z+8K(8p@ZPX+}K}4v=llRm92{`qHfmE@F=qwCiB*@Q5$izdXK@}Su56B|G?a5351`~ zD4UU4uomG|_{}m1zQ83&TQ-Aeb!xWZKwIAoZ3?@PJ1WaRi!5S>6gX4j3iB$nK)no4 zUrnGl!h-SHIUE8^bKJ0UugdVzsq&m*Wc1OH71j=BAh17Dh%?=zk zSsoJJnSn$$NJ=$36u1xK3Dd2sFj&H|xIVY26B7{KtS8Ib*n!|)A`(x9>q}=A7ib_{ zSCHDT&@_*KeG~>BZY+bGH?%rf^aN|!9a=tF>FrxSQ|b0CzxmM73r%f5eCJnX|K76y z`J(^WL*FxH-=4DXP{H|K;P5vumjYwuz*v>*wZo18C`r2uLdmFd7tt%iIlVgh*_opMH1ap^ zlwUYy6#=QicmAQ3$&d55^MyAaNuH0~AG&YpD?k5uq3CyTD%MnrzQF1L0CGv%TbA|~S$@>($DTTR zZ$%zB{6&Yqf&FSp8ZS%ZMQOY;u(jYWxGPTIt@l2BrtnMy<*kx5RhFiT(iB5^?J4ZL9DF?5ECRHCIIcKt159$FYQ**cfKTDC`%WL(uKw#QzhwQ zS-M!1En{SK-%dBg0SkEiA%hl4fI#jd+% zH^TE*b82=rSo4Nke(!bht6OaAm`$W-5Xok|4`UzU{CGOpup+$|e|cddeBzCX6KCE$ zcgpOl)$27|Q6oFVlom9Ki)p&`OOVdvIzrhb?wKGqJZ zuWke@gRA3@>HGKVl`jtS@MLcUE2+oy_51azaX-Ji%C&;$J9!A4Rn%j C+T`f~ 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..ba2522e4e1920f2a4b087c8f5707cd67fd893ff8 GIT binary patch literal 2274 zcmb_czi-<{6h7*wEm@X-NJ``+_Qgqq*r`PXMV2CNQ5b3BrVWhRX;B6NLF>*EW0J=n zkCNq~@X(>7fey{+DRt2)Xr!bKqX1q%GzVvSZI%cozrrmJqq@?HXhm;D{oI|6QP~8 zChaM03hXg$I)-SHJ_0-%b0sL~MBMREa9C5a*zwQ?9!`9CqukQu;Sdh2P1me0g=iChNEl~W9v z4N-$JT_$sYn(ag3A*d_lDxh!}Q*0eA%)gRHT2O+l;W$hf!eoy32*#Ne<_NkYzA(5P zeafnawZ_>_>y;D~rjj39hPMsIxc-sru85uc7TYu|Pom{SM3?KI)31H%iPM>}b?SMr z(P!q4=>Q_#MeP3bCF9$sQ^U*`o=GTXTi9@2%dCch;cDcxlF4k;O%IEf3oDk@!ZtM= z7}pJfTg=CX5Y%=BC0H=*dlYZ^PE{VwuuRd4a1Nz}l8mTRT=hApj_BX2f;SlUnAMY&iX>UO<_qDe7{e0 z+0AW9K_d@hXSdYV3li|;RL`eDTCX;A*amdV`_3lw9irQyr%|JP6jBqU!x+R)5C?;& zL>TWMU2$P&cw3 zK&DKeSlEDb3tVSSnP8*AOvtpX2$!=>i`tdl$w&&LA%Y2Kf)T#28{KZsHu@Nh}-?H0FpP-l$JMCZzhA9LD4G7;oK6nU}lBAR*r4)m$hEs}j`=3b4`oS%r6eXo7 zDaF{HGL$mX3;fod!^QTU2SmR?nNlWem2kVxwNDqFJ1mdK`FehjVm)3jttE731Hn(k6pk!-2i&8;eu zrcBu!M~P{VcCFdiv3Ayz5rV};8#`EUek>+H0%Ru$vdFLIpo3{NLcl;U!48lgG&~a+ z`Vr(i=iXagMN+Z{8z9?iT~=4!I`?(n=iK|RT3VVkeEwP6e;Mr=*0ldYKh&pATtjDECEPSB(Dv|~<8*beU0nb(SrNAEbcm2>PYUthM} z3Ba;{L*2l`L^?Z_cI-c#v|W0h$WA(rUGUO?f}ah6C-O3#_1>f>uI;+$6)xMxacPd) z>5;tYj@eeV-m$$&r%;VuD;D!ve{8sj;eS-q^shg_#V48=$z_$xl)8MY!*%OGLCqc=Z3XM4u`>K&b zv067m^^$efNYSk}NZ8frsO>rJRIM&woMtqLPN5>rt?}^fzOmxC-8X>|*?o2)>` z=Y6hM%-+EI^|~{KEcL2ydV0FgvZw5Pae}(rH|CA!`>>cd(xZ04c1*A6^i847zI^Ul z-^7eJRxBJ$?cd+$<~+N1!enS}AECpIzA-xwd~{P2Gu2k~F3odGs50sh6>q_R_c;`E z+VA38qUFw>4^tnc?rmFW>MA#N&7E3IwB3!C)*QPR{b}Qm8~-%%X`;0ESZU+2g~ai4 z;&>@`{A;|c4OJWDBxZdy!fl!`MmIvVzbCrsv$`9Z)vjo>`h9}C;ok&KVb(k4v0~PC0BxBA-y52;^W-4gKlM%#ZnUB6q`Zw&72;jZlPo zn--Jc?8IIA?|u&jaHQ48kGzu~1$6lSh?&Q)X9@KUGDe4du* zjZ`YtgWoHwU47WO+U*b)k_cuj{A*mir@a^Z1Y*Mr;OYBXn6-TnE9~B>c>y-K3lj+O z7N6HfbgS-m^DW(zf*l}%k$`~OpZRZOBd-JdrnNVtuWQq~)i@u+dkuIm647QOVNAUh z4KdPaxG%ak8wDOWnLh+?y)5K}ku4TH`%O=vFvJZ|1FW;axZ+3wL)^^uOow=5Q9J_T zPuY&ZouM&2$JZ(rfRSLS_Q*&sn*�rHtHWRzhREW*Wc^M-BYJOk9=8u{D}I}cV{ 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%0DOU!s=5~ABqryZiFYOBxZc_X;<=hPw#hWqrm z9wBR(!ByRJV)VO_bIWm#jO)}<&3d}os=P^JFFBhK)eirrzbn+`osrHf^df1!&L7a* zYyFBcSl|jQA>6=TuYB3 zingm1{)XWnC~2W@MLSpue=FKErSSJl%_xPxmGDnIt!P_I;qP~=v!b`r*zIGGkNVC^ z?8#F2yHsDNpTLoeE6O#^dLO)fD~s(f>iW7RZACd8N$Go+v~V$|Yg=|yHgBizwkMWa z4(hN%A5|1|?Yw?bUy82N=@iIEl>0jMr*NWUs7Q6_ui=dqWzP<3Z z9r~*jLwb|mzNCeV?b=qOvUx|v*j3rMwX$JL<>0fGQ|Fe}zNJ$$k0@uO-SjkEyrMs& sKeMET3rE)?iMdU850&(d3;M>gzHup1ueaemOj&#t)gqf#-exlSza6-eqyPW_ 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..dcf92f58b2649934b1b275de1f2aff868806ffcc GIT binary patch literal 3504 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 D&D4x+ 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..b727a6d43660014a9fae9a262e42f1f591c8e673 GIT binary patch literal 1415 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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..4d5f0ecf5cb2c97f5d8155defb65dc67a2845b28 GIT binary patch literal 14764 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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..1f7a39ccc208c3f0a7841d5e2a79e0a5bfdddcf8 GIT binary patch literal 3878 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 BwT1uy literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/flask/__pycache__/wrappers.cpython-311.pyc b/venv/lib/python3.11/site-packages/flask/__pycache__/wrappers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..445e718d385b827301cc604a89fcaca6a9e06567 GIT binary patch literal 6858 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 Zm)+wc{=5Qx*k7%$eoDQ6=`$p`_&@G^A&39~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/flask/app.py b/venv/lib/python3.11/site-packages/flask/app.py new file mode 100644 index 0000000..12ac50d --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/app.py @@ -0,0 +1,1488 @@ +from __future__ import annotations + +import collections.abc as cabc +import os +import sys +import typing as t +import weakref +from datetime import timedelta +from inspect import iscoroutinefunction +from itertools import chain +from types import TracebackType +from urllib.parse import quote as _url_quote + +import click +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.routing import BuildError +from werkzeug.routing import MapAdapter +from werkzeug.routing import RequestRedirect +from werkzeug.routing import RoutingException +from werkzeug.routing import Rule +from werkzeug.serving import is_running_from_reloader +from werkzeug.wrappers import Response as BaseResponse + +from . import cli +from . import typing as ft +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import g +from .globals import request +from .globals import request_ctx +from .globals import session +from .helpers import get_debug_flag +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import send_from_directory +from .sansio.app import App +from .sansio.scaffold import _sentinel +from .sessions import SecureCookieSessionInterface +from .sessions import SessionInterface +from .signals import appcontext_tearing_down +from .signals import got_request_exception +from .signals import request_finished +from .signals import request_started +from .signals import request_tearing_down +from .templating import Environment +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIEnvironment + + from .testing import FlaskClient + from .testing import FlaskCliRunner + +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 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, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "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_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "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, + } + ) + + #: 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, + ) + + # 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") -> 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". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) + + def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Opens a resource from the application's instance folder + (:attr:`instance_path`). Otherwise works like + :meth:`open_resource`. Instance resources can also be opened for + writing. + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + return open(os.path.join(self.instance_path, resource), mode) + + 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. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + if not self.subdomain_matching: + subdomain = self.url_map.default_subdomain or None + else: + subdomain = None + + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config["SERVER_NAME"], + subdomain=subdomain, + ) + # We need at the very least the server name to be set for this + # to work. + 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 = headers = 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 + 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) # type: ignore[arg-type] + + 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..52859b8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/blueprints.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +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 + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + 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") -> 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". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) 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..d4df280 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/cli.py @@ -0,0 +1,1111 @@ +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. + """ + + def __init__( + self, + app_import_path: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: 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._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 + + if self.create_app is not None: + app: Flask | None = 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: + if value is None: + return None + + import importlib + + try: + importlib.import_module("dotenv") + except ImportError: + raise click.BadParameter( + "python-dotenv must be installed to load an env file.", + ctx=ctx, + param=param, + ) from None + + # Don't check FLASK_SKIP_DOTENV, that only disables automatically + # loading .env and .flaskenv files. + load_dotenv(value) + 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. 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:: 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(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 + + 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" + + # Attempt to load .env and .flask env files. The --env-file + # option can cause another file to be loaded. + if get_load_dotenv(self.load_dotenv): + load_dotenv() + + 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 + ) + + 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) -> bool: + """Load "dotenv" files in order of precedence to set environment variables. + + If an env var is already set it is not overwritten, so earlier files in the + list are preferred over later files. + + 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 instead of searching. + :return: ``True`` if a file was loaded. + + .. 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 or .flaskenv files present." + ' Do "pip install python-dotenv" to use them.', + fg="yellow", + err=True, + ) + + return False + + # Always return after attempting to load a given path, don't load + # the default files. + if path is not None: + if os.path.isfile(path): + return dotenv.load_dotenv(path, encoding="utf-8") + + return False + + loaded = False + + for name in (".env", ".flaskenv"): + path = dotenv.find_dotenv(name, usecwd=True) + + if not path: + continue + + dotenv.load_dotenv(path, encoding="utf-8") + loaded = True + + return loaded # True if at least one file was located and 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() + 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..f2f4147 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/config.py @@ -0,0 +1,372 @@ +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}_" + len_prefix = len(prefix) + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + # Change to key.removeprefix(prefix) on Python >= 3.9. + key = key[len_prefix:] + + 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..359a842 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/helpers.py @@ -0,0 +1,621 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import lru_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") + + +def stream_with_context( + generator_or_function: 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. + :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) + 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] + + +@lru_cache(maxsize=None) +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..ede68c5a0b214521ee66082ff42cbb75d6b88c01 GIT binary patch literal 6926 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 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..445dcefa4a1d5c7487600c663b8c9ab17f98b3fc GIT binary patch literal 10041 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 B0we$c 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..68f5d1958af25237847da51509a46445d3bf5deb GIT binary patch literal 16634 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

    +{% 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.5.dist-info/RECORD b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/RECORD new file mode 100644 index 0000000..df17048 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/RECORD @@ -0,0 +1,57 @@ +jinja2-3.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.5.dist-info/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2-3.1.5.dist-info/METADATA,sha256=PJNSUFNBwoqGA2vce2XSP8M_p2EYqAHYI7hoWLABtFo,2593 +jinja2-3.1.5.dist-info/RECORD,, +jinja2-3.1.5.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +jinja2-3.1.5.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2/__init__.py,sha256=zpt8UHzpS2eB1c04kn1LkKkaXLXXcKd33klq7UJGIgg,1928 +jinja2/__pycache__/__init__.cpython-311.pyc,, +jinja2/__pycache__/_identifier.cpython-311.pyc,, +jinja2/__pycache__/async_utils.cpython-311.pyc,, +jinja2/__pycache__/bccache.cpython-311.pyc,, +jinja2/__pycache__/compiler.cpython-311.pyc,, +jinja2/__pycache__/constants.cpython-311.pyc,, +jinja2/__pycache__/debug.cpython-311.pyc,, +jinja2/__pycache__/defaults.cpython-311.pyc,, +jinja2/__pycache__/environment.cpython-311.pyc,, +jinja2/__pycache__/exceptions.cpython-311.pyc,, +jinja2/__pycache__/ext.cpython-311.pyc,, +jinja2/__pycache__/filters.cpython-311.pyc,, +jinja2/__pycache__/idtracking.cpython-311.pyc,, +jinja2/__pycache__/lexer.cpython-311.pyc,, +jinja2/__pycache__/loaders.cpython-311.pyc,, +jinja2/__pycache__/meta.cpython-311.pyc,, +jinja2/__pycache__/nativetypes.cpython-311.pyc,, +jinja2/__pycache__/nodes.cpython-311.pyc,, +jinja2/__pycache__/optimizer.cpython-311.pyc,, +jinja2/__pycache__/parser.cpython-311.pyc,, +jinja2/__pycache__/runtime.cpython-311.pyc,, +jinja2/__pycache__/sandbox.cpython-311.pyc,, +jinja2/__pycache__/tests.cpython-311.pyc,, +jinja2/__pycache__/utils.cpython-311.pyc,, +jinja2/__pycache__/visitor.cpython-311.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=vK-PdsuorOMnWSnEkT3iUJRIkTnYgO2T6MnGxDgHI5o,2834 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=9RpCQl5X88BHllJiPsHPh295Hh0uApvwFJNQuutULeM,74131 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=CnHqCDHd-BVGvti_8ZsTolnXNhA3ECsY-6n_2pwU8Hw,6297 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=9nhrP7Ch-NbGX00wvyr4yy-uhNHq2OCc60ggGrni_fk,61513 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=5PF5eHfh8mXAIxXHHRB2xXbXohi8pE3nHSOxa66uS7E,31875 +jinja2/filters.py,sha256=cvRI2pqXNMzw8ba41VOBpgu_wu1r-l1_QxwD6yVoJ5g,55025 +jinja2/idtracking.py,sha256=-ll5lIp73pML3ErUYiIJj7tdmWxcH_IlDv3yA_hiZYo,10555 +jinja2/lexer.py,sha256=LYiYio6br-Tep9nPcupWXsPEtjluw3p1mU-lNBVRUfk,29786 +jinja2/loaders.py,sha256=wIrnxjvcbqh5VwW28NSkfotiDq8qNCxIOSFbGUiSLB4,24055 +jinja2/meta.py,sha256=OTDPkaFvU2Hgvx-6akz7154F8BIWaRmvJcBFvwopHww,4397 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=m1Duzcr6qhZI8JQ6VyJgUNinjAf5bQzijSmDnMsvUx8,34579 +jinja2/optimizer.py,sha256=rJnCRlQ7pZsEEmMhsQDgC_pKyDHxP5TPS6zVPGsgcu8,1651 +jinja2/parser.py,sha256=lLOFy3sEmHc5IaEHRiH1sQVnId2moUQzhyeJZTtdY30,40383 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=gDk-GvdriJXqgsGbHgrcKTP0Yp6zPXzhzrIpCFH3jAU,34249 +jinja2/sandbox.py,sha256=Mw2aitlY2I8la7FYhcX2YG9BtUYcLnD0Gh3d29cDWrY,15009 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=rRp3o9e7ZKS4fyrWRbELyLcpuGVTFcnooaOa1qx_FIk,24129 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/WHEEL b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.5.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/jinja2-3.1.5.dist-info/entry_points.txt b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/entry_points.txt new file mode 100644 index 0000000..abc3eae --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.5.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..d669f29 --- /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.5" 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..f476176d3c9d1c0bec7fcee99148f93f47adf094 GIT binary patch literal 2170 zcma)-NpIUm6vs!FZQ0u8Mc!@NPFfg&O}J^g0BL}FOIpN%QMW)b7lIJ1Z zPC-w-_t1WWqMxK!9toWa^wgVy+;ZxhacFB2A1Xcl@#BBqtbC;Ys8oswKEKxfYX4F| z=pS{Fea7Cwo1b$C{f2ymk)QL&!dx_l$8w7Eza}t zM?2fEe*ZS0FI_7TmTO58#i1*SMQA&q#Jc2xl!RIVwc;)(*4aRI7~QkJkygxEFYpQU zDpE#we>{C|i2;>v-;y0yTA~}rj7tGsLp2iV$D9ZeFbX}W4?l~=5-#1aD8Oj3KJj7N zUcecR2$g%qf1yIqPHtE^7)atVpB%bghk&tg5`^S@AYircH#JX52Yas|%i#q0rx+*<}&ZQE|oz{_4P=VfY-S8dTuz9*bpQn zo^;%boa+O<8p%4J9*5W|hn-nOD*T85a0;0r3T8 zEh<@3vaDnUWH`~4K`8jDGS-x=E7?$DDcJ-WmK>)?xO&ta=TGzoEcEuZ-C+^2V+I9a z6YB9nEQxOm$#e3hfqS7fzc{!d=O@-Gk$?!=Poy z`gH*3x^Ig>lHK^apoINWy;4509VeiHbez3-@OJ8Pq|5IK--QLKM_W9DKZC1$E|$iyNMYodX|`xqR$dDQuH`6BSlAv87X>_ zn31A`#EcYuk(hDUdiE1!#9cXGCdh~sJxa_-%|T$yyH3NHNauW&AS3P?`NMPmJV8dJ k=s{veitNOU|K}LP!Yrw|aX5z$oxiK|uS@F7A3#O@2U@|G!vFvP 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..81fd305b34a9e47e5a06e1c57b539680ca343323 GIT binary patch literal 2186 zcmX|@yK@`Y6~;kw9L4r{Ql(3k&hcDfoD^v?`4iHlbCU5;A}moR2@Xk1qbiFxL~>0m zDFFmYfJ-c1yNe|ryLgaz&7?__q;MfhremE8R=Eu~qg1Z)T~8cfe)oL$oNw=*yB8Rs z_Q4151@Jof$zLB-?*sxja`MA#;eX=oU5H#@DX=uR68I!A9|#2=&HZ3nny*6J|DS&{ zzclyzz=sR}l7`=X@oOylhd(~~OaE^Q`+M^rsjp(}tJF)4y&S)sUPZ2=SMjUFRq9oS zy*hfm!(N}hZe3^D^~v=qyDneXuItwpyLP_OzG<<4Zhu>4-?rY^?2Y?oOnR1)o+ten z!63bYP$S($aOf=0=^o1qKZM)2%~C@sw1kR zT8mRHMYS~5b}&(?mZMsUY6jINREM)3qxy*IaGFsvQ)H&egws^X)W~d+*(S3~7Mxa$ ztPxpo+6l5#2+zod)mF(ak!_HTp6n?#;BCaHF`@>%PMn++IcaiWbyRY)$# zl+IykMyZ)ZNKc+{1)lHKNtE-axg4`^*C2|e&u%s6wZ%E#VJh;1Y>cZVkQy1>8O5GfFOVl-}7o}c| z`rFjsW7L06{Veqlp-!pap}tFlHVr&RgG;)=bGZ1DF57g8#N`ED4(W14!!)CzN~1#> zApYfCD{G@~6@xneY9PmPi7hGQS7(YGW zrvFs`e-l;EW#FPXfoGhViNxrH#~^&I2%V{X1++$?evHFLzxDYsCz#=N00-iY%C zR&(OqLBo#A&yhTj^7AtUhc~N?H(lN;Gv4ZRH^aEQ&)w$;b?!RcMQ^Uh-9Ewv@8i-w z!VqCPQ>L?sGK)N)#WHLbJDJ7KX0ZxXYZgD8#m{GMlg-@rtUI0cbvElyZxoB&D9xK_ z{w8`P@=cNVn8=UCQBfS7isP0zZVNps^rX;tgl;gQ*F;GXrHClOXe5N8BeaDv73C@u zWk*y}OjHg;RbiqU6IGXqnj&fyQ8$^W_kRXiJJqUyDmm9GQ4c3eVRP2>@@x^|hp|CQ(hg5Ge&blVaD`(hZ1oA5460 z=MT8{Sh)xZdQlR9uAv`H?2M;^;#y~#jE*@kT>-OYw zy)OaIq^E%cnZWjkvX5cU&)VodYkPjSAw>h3F`CJaCw_La2Qk_Ak2?iW^b3g!!(akO ziVnao3OJ=gG9kqdu%vMO!m}vEv$$WV<6sK)9*}0U0lI#{Ld7~p!a48dp{3yFR`~wsiw{C<^Xc0C z#e1kddGaK<6nY$539qk)*0zEVw^mnz_rl@NKYb8d3vDcJg*SqaLu-$NE6ewS>rb~H zhSz>|_v4R)o6B1vw!ZlNYMa4F%WIDoe;NFAc?oMQf3_UjxV!%JyC45%HN1ode!KB5 zdXoPFHW>zgVQy~jRp4Fa`?vq2!23T<|9tls{(Rt_KmY9C3-j;K|0jS!xg*~j_>U0y EFLd-4qW}N^ 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..1826279ff96fea7479cde9cfbedae1c81d4f3b14 GIT binary patch literal 5646 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 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..6fbb4385679a55a8d23bf1e5625bf521b776b0b6 GIT binary patch literal 20968 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

    IB?u3p;Xso<24RofWcXPn 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/constants.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/constants.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..137d6b48da0abe3bf2eaef664c0440b89e46bd8e GIT binary patch literal 1605 zcmX|?yRIBX5QcZbAT*MN3?fCHIJw3IvecYFEU-oE2KLY{c z2@p?0N=(WNSaRlwuVxRdW~%<~sjmLJF1^3szd!8w{qo_T%Wv=PcK_($zu*22yit>1 zck}M&-MqirJ$%Q0fvGjt@wgtVO~%eVe)ZM)v=}Q%bTast-NuWSW^7cEni#t_N#NqT zv2C#3wOowtOBXZwNz&Y-nSxETZ^i{%t8qETJZChMk=0m$bp@)5Ytp)uVH>b5>vHOo zx2jJz1doqm5ljZ1RtLS<$+uoMgr{C=uV%KZpL!i;5Bu3W-Rq)i11!nc>U9d!9AG}@ zB+ks;>syU1QX5;Ln~@;?z=;OH9d8L7OA;=mKvYV`7T0RsbWiC#zH(r5unxM_{|_oC zN*xYFO<9@)?o^gL?+59N$L*nz3m<|thhCkSrP!07tvTwENy8neRX}by!m&t!+3}1g zE0FTmb#?A%ZxnA zH;KQVoXNA#CKu-s$rdrIE$rd7`d675O9%|4vd^$`!nWmNzYn*Bmis4WO41`B83eKus{1)#@zeqB~FHk_+(kip5f{ke1popdhvHCXD>^!@u$`}J? z%_ExZINEWB9Q!yfl%{~V&}-CbqoO!gyF{bmJC{Kfo*PB!=T2aW1ne(Bqtf8ixQbZc z3wM;!G)0$-GV6iQj()lT506f&OmF67i^uUvj(U0v2>Qb5#BnrL`VrR?v5DqHR|)cD zDX9T1h2))b=xwDPPd%)?k+$z2?*D%9-LvQ4JiY$*hpQi-UjOv$`PWx}?B3{o`}Wm% z%u&WQ_aLJrSI*p(^GH9r7j}_H^_-lY_;!1HJI(^1ylUf*#}>ml<^1A$fgSfsE+afo zBV9JG=SD6+fBfXhNCxE5YBz6nyz%MAem3f@sdqwsyq@2F@Ff=y+kaKwhmrmb)Q=Ib X-`(%`ukU^I$)|tq9$cPskNJNAjlfDF literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/debug.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/debug.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f99686a434ec25fced985364f08843ab883c2f8 GIT binary patch literal 6765 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 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..6cb20934f94b6b3f8ff7f1cdb88677eb69d07d72 GIT binary patch literal 80628 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

    t;0z=p! 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 pHYkEf$kSpwlks75`KcTh3+G%QCcvvgyd8 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 b%P+0%NpujwBpbuU?ccDLUvARQX6yd}=c*Bb 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..255ca49ae11006fb73e48fe26a15e95f19db5d83 GIT binary patch literal 35713 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≈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 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..1b4799e23c65262e4f285ea7bf613bed91b72797 GIT binary patch literal 8012 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/nodes.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/nodes.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bceeda009712876eeb5eb3070e8609daebc8d549 GIT binary patch literal 64531 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 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..a7aa8d221d4b2d01f7748a0b7a0177ecdc473366 GIT binary patch literal 2901 zcmb7GUu+yl8K2qPJKrCl?Ko%bBvm@1PTYg`4mSw`5&=nYONwF;@kf?h5f+L

    |?jg(@EU!mEu=!dj_PB%b5~!&k|_A9sS3WN)hsJ9P}EDb=%*B&lYh>g}Br;d|ENwglqbV zx>+$Pfqv3Y)>D-fCETbD9quAB1)P+hu4gJ4ST)4Wnm!BpZraVb+2b?Sl$+ZyD>;L_ zLEPaD;^ukkQG$>s@W!n&>>9U7am4;BC1hclGtmgWx_6gL7D|sR77FHwK!tV?va0Z1 z##bAXE9Jo?vjdmah3i$f(}{*I6Lczdc*TU z_Oh*&u6m%GRzNhvS6GWP#|}`aEBf*dZPkJlEXlUO$`X5BNU+kbH+=pI^Mz=zW*~*{ z89U zT$iaeuz3~0=RB*`SD}y~8u9JfFPlDBrR*o@!ue0YaimD2WFTCwpffrTodszJ3Q^(` zrgC$^iYG--2R$Ma7e+aLG$k=8qm<-fQwENKVhv`Upl(`ZI4E zVLz$}sr99Vy@-c>HM76l*iQEP$G>edDD@G@dD52!kxK9W1QEp0;Hx29_5fM%ECv_E z5a1+OgG;m=LW4ovhMv<4YVGJOgSKenS_mJ6wI^%ITj4>en2Ivr?h-xnnQ!SHaPa zy$HNkt5tUS3im|={Zn2J>wbArh&$F254g0!|7B2YrR;l)<;GgLEP@NA+1WDaz+Y|H zTAC`?yr5>kR_^OjYOF=+{%9POD!{8|fvl5fDRScUyIG#n}mu3 zH45rb-@{O+Qb#q+O%IF`$5&R z?vCTRx-^!0b1%ROH3npz?43EkX?D_6JNl6)VN%COWZH5`MX5V2{0``ci7^WA{zXWl zcjy)|1`_NMu%5shw^~2Z+H{GwjX%;K5|6YK59zPz+cfM$O~B62Pr1QVl2(Qctm{kI zK9;b((^2Yn{}MWyg?U4!+lEU|^(O-egux_k(^@ZJNSoBqQ@Z`d7`%*bk(UN_>R)Zs zL?$S?O#-t;Rui{Li?%8FFEKCCSKz%ARA(ND*qON~shUs)qP)%^&#`pIMp?*PeU&-< zFrVk(GK-Se@q&v+s#4UgW)R9ITvBe7wv`2?0dgPRtR+X;8}){O%MbFln3R(^uZsX$ zFHZxBGM44|wo;a*5K*WEY+Xl^JPX6SlSe@`pxcYUR3892SSQ^S89Vo@<}X|KTAk79 z?S-Au%a6YUB!1q1J^pT*&(dW03-{gM&%O8NZf>TNo9U8tW}<5hu=B;s+tb@`J)GH|c|Y7OTy~}%Sy2HNG9U@b&eM-!! z@z0QSiFsoD;8~UwPIXSc)Fm`OaYXjU3ir)!0_F}54p7^|W=>&=`PwFLPnF?wwx z@lk;SEt(oQIRV@_MT=R?slcvt%Zjp=1^*wQLPCGovfgUie$0_mxB-i<96>S+BuZQj z)-;S!{t#t{`@UsC5}yOU!W8*-47M&9NX{T*4F~|+`*jVP1h584>O``zS2*?H&29pF zGcP}E#=Wn7{lld0JUwZHjh#7k6 h@lE~tfPYxio&P2y6BOY4Uvhu+Q=I+mb6DEG{{S~v(jEW+ 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..20f604d78cf858957a16c825fc372e77a028d4af GIT binary patch literal 60077 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%0DHEu8 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 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..fcda8a7a6129169f0f9e03ae0093e8842b8adbda GIT binary patch literal 19272 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/__pycache__/visitor.cpython-311.pyc b/venv/lib/python3.11/site-packages/jinja2/__pycache__/visitor.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34d5499c7d9c55f9fc83e4316b00dbe39e072667 GIT binary patch literal 5749 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 DIViK9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/jinja2/_identifier.py b/venv/lib/python3.11/site-packages/jinja2/_identifier.py new file mode 100644 index 0000000..928c150 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/venv/lib/python3.11/site-packages/jinja2/async_utils.py b/venv/lib/python3.11/site-packages/jinja2/async_utils.py new file mode 100644 index 0000000..f0c1402 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/async_utils.py @@ -0,0 +1,99 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +if t.TYPE_CHECKING: + import typing_extensions as te + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True # type: ignore[attr-defined] + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return value + + +class _IteratorToAsyncIterator(t.Generic[V]): + def __init__(self, iterator: "t.Iterator[V]"): + self._iterator = iterator + + def __aiter__(self) -> "te.Self": + return self + + async def __anext__(self) -> V: + try: + return next(self._iterator) + except StopIteration as e: + raise StopAsyncIteration(e.value) from e + + +def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + return iterable.__aiter__() + else: + return _IteratorToAsyncIterator(iter(iterable)) + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/venv/lib/python3.11/site-packages/jinja2/bccache.py b/venv/lib/python3.11/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..ada8b09 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/bccache.py @@ -0,0 +1,408 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" + +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: ... + + def set( + self, key: str, value: bytes, timeout: t.Optional[int] = None + ) -> None: ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/venv/lib/python3.11/site-packages/jinja2/compiler.py b/venv/lib/python3.11/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..a4ff6a1 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/compiler.py @@ -0,0 +1,1998 @@ +"""Compiles nodes from the parser into Python code.""" + +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(new_func, f) # type: ignore[return-value] + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: # noqa E721 + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "te.Self": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "te.Self": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in ( + (self.filters, visitor.filters, "filters"), + ( + self.tests, + visitor.tests, + "tests", + ), + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(sorted(vars)): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, sorted(public_names))) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import async_exported + from .runtime import exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline("agen = parent_template.root_render_func(context)") + self.writeline("try:") + self.indent() + self.writeline("async for event in agen:") + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent() + self.writeline("finally: await agen.aclose()") + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline(f"gen = context.blocks[{node.name!r}][0]({context})") + self.writeline("try:") + self.indent() + self.writeline( + f"{self.choose_async()}for event in gen:", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + self.outdent() + self.writeline( + f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}" + ) + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + def loop_body() -> None: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.with_context: + self.writeline( + f"gen = template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)}))" + ) + self.writeline("try:") + self.indent() + self.writeline(f"{self.choose_async()}for event in gen:") + loop_body() + self.outdent() + self.writeline( + f"finally: {self.choose_async('await gen.aclose()', 'gen.close()')}" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + loop_body() + else: + self.writeline("yield from template._get_default_module()._body_stream") + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + # The position will contain the template name, and will be formatted + # into a string that will be compiled into an f-string. Curly braces + # in the name must be replaced with escapes so that they will not be + # executed as part of the f-string. + position = self.position(node).replace("{", "{{").replace("}", "}}") + message = ( + "the template {included_template.__name__!r}" + f" (imported on {position})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + + # ``a.b`` is allowed for assignment, and is parsed as an NSRef. However, + # it is only valid if it references a Namespace object. Emit a check for + # that for each ref here, before assignment code is emitted. This can't + # be done in visit_NSRef as the ref could be in the middle of a tuple. + seen_refs: t.Set[str] = set() + + for nsref in node.find_all(nodes.NSRef): + if nsref.name in seen_refs: + # Only emit the check for each reference once, in case the same + # ref is used multiple times in a tuple, `ns.a, ns.b = c, d`. + continue + + seen_refs.add(nsref.name) + ref = frame.symbols.ref(nsref.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRef is a dotted assignment target a.b=c, but uses a[b]=c internally. + # visit_Assign emits code to validate that each ref is to a Namespace + # object only. That can't be emitted here as the ref could be in the + # middle of a tuple assignment. + ref = frame.symbols.ref(node.name) + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/venv/lib/python3.11/site-packages/jinja2/constants.py b/venv/lib/python3.11/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/venv/lib/python3.11/site-packages/jinja2/debug.py b/venv/lib/python3.11/site-packages/jinja2/debug.py new file mode 100644 index 0000000..eeeeee7 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: t.Optional[Context] = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/venv/lib/python3.11/site-packages/jinja2/defaults.py b/venv/lib/python3.11/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/venv/lib/python3.11/site-packages/jinja2/environment.py b/venv/lib/python3.11/site-packages/jinja2/environment.py new file mode 100644 index 0000000..0fc6e5b --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2/environment.py @@ -0,0 +1,1672 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" + +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS # type: ignore[attr-defined] +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS # type: ignore[attr-defined] +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping[t.Any, t.Any]], +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: # noqa E721 + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: _env_bound) -> _env_bound: + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = missing, + ) -> "te.Self": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.5 + ``enable_async`` is applied correctly. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "

    ggYZN1)s<;?j(`1QQ*A!3qqoeA@Poc!`&-iT>WA( zveU<#_3Y3x4MgA{@&78JzR%f1-h5drvrfEJ<=%l8X`fLvih&({Kd-ow}I>sA^QUC2%&e zj}kY!K|N0id3&i|UBJ1P2J>(&Nhlui?i`@sd(y&MgVv};v?eX8HES)ik;zuIM-AhA zxUETOLfE9b6Ok?9NlD$Mb|AN1?NvMR-GSd-_}-@OR=4B3Q{AKPz;~D02zR=VUBxO( z&|{9nMPVXvgIH`Kiyo1UMZ^VV$nmj)9&xAVggsip1Qds;n9N&J5GRKCAQoQ7!U+%- zM_V@B;30&LJT4Z0l+n}_MX1=fbcj(w0341@9e*li8mf{-@JcREk&t!(6$PJBwF&ez zgUG+!0=am&-O_A7P;F)%hqI=y%lUjt zjgwCGwY9^c;&y`9z-DF?%U%iRC^WHpGwwOicC6kM;}AN|P9Vh}I)O`&HDZtZ0&G+` zx8o8bgf?I?{ZH*iOcYjoRNN?yL(R?x1%gzD5-r3uI-ShUu?R$_&-R-nSUN*M7^Nlov^XgD9I zh_-uCu%Wypv+yb+uKm#QCUY;gkhqR$D+;jkdVQBdOQEW%zZ6~y>qAQcqjxC`(mTs= zLC`zh*TJf|6vho@;EkZSx37pxA$Pka7P7V!T<%4#vuqn~9Bo{MrI5ET#CIcp+0%~Z z<9n8ZXo>Zz#(eXZv5@jIvOi-51Ih}EQw3T1?K_Kgs!FUSi6mbmh~HD7BuR4xGE-mnQys{voz$wKN!EaDT}Na@?&u2?LP_yW z+C?0rv7I6U4CK=@@(gZRGKq+TO|ccgt{P$J)Rp~^2|$>UYsCuT33NAD=ozfvUwkaqz^`&g!LOBwjSW{o4SYJ4 z22OKSCB>t!5ul?y{aXasT@#&K8w~&)7k=aP4g9{3Lb9jy0kxxpNZf=C2vW~VYCUu% zx0=HZeOt%s>`L%Xa~rOSoAz#Y_CPVUo)Xu`H%5POy14r=KJRSbQ|uevFaY?cwEbjx z`^jSa$veB{mC@DHYso8PcbeN*o`E)7ec^V??prOp*OR4|edU&YMf-EdRims(=w zmRQmLaPMIsP-G!co?~Is4@__ANO;4_UpZw7(4s7n&d41uv zh4uW^%hxU!+Yj&$tV`3udi63wf0!oMaq~PbxDRyP z7NVBE-acpr-J1P^$a{0=x#L>yV=*2O`$8wIg^}ti)?Yezh-FSs&885z#p6cxV<1E< ztdmi91&WY3>*T%bp9JtMWhI=?VwA$px{JxmhG;qIBp=~N&220BDm6TvcI8=! z;mVm``r~OJrfcf8RI#}aA6Ds()VaF2-nn}DwlsK48hk7KR`N&DlJt04db}8UoGq_s zWgS`iZ;VU#qweFl2gOe4Pq+dZ>dMfY=<#j*^QZQ<6_=3a{{w$fP$o=J7U3d$K#;<48E+6T95u6B{V;KTH0giC*}VbcTia=;j1l(u9E* zjr4Kkd1EE?&myaEq%JSGTGk7i_ylpuVKk?U-mX*p^W)G>@#bS|pI#5$?isq(GxSzR zsprvh&!bKSzVc}5JS5X>;)JntxeXWkN?^mO3x)DIf!1_ERPkt=yNl)HgUWAz^(2B8)~Wh(Q-HDXBDyeK_H(cM4lt?IRf7%aGt;r z0Q1}JEAHFT-u!fP+A=Sy7&%3TLmPOhAMr*+4A_zknv+Fx#k>mQ(A ztVv)tKMMntx{j5*j-j>GWvk>Kpx_Z)M8S%yh_XzlF2nI!*6W8f3xz)t z=oLElA@(XNG_`L=+@Frkh_o5$-0EoRYFIwAwLKih*4zuagdM$`z4BI5U-;mbPzM|r z8^YaNf)}($!$-CRFX)L8_(LU`x)X9NW!8Md{6enLNGqfC&E} zk)i=-1Q64TXjU4gvFCc?h)y!XZkBaAjje>}EJvrSf=aY{)2KI7M(cv6pD$?n**Lw& zrqjDfy2KjMD@6OgdWzo9ruQdGw;J|{c#FXg-lM$ts|Cl!9U@$MKUkT4k8TMPgcjO1WW-ryW%6prrPd}iV$bG+B)YB~D65S7YpEC7nmG?>_F5UcKt?@m| zeZN}N-z?%n#1Clh$fZ85a?A*a(0;HsNHzCTO{=^&Es7AM`tUuL|NebS8KeFm-yoHO 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..f9b2e8f --- /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) + + 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..2bb986b --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/json/tag.py @@ -0,0 +1,326 @@ +""" +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..f7e0eaef059f8d0fda79db6ad555383e94eaa43c GIT binary patch literal 35466 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 A(*OVf literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/flask/sansio/__pycache__/scaffold.cpython-311.pyc b/venv/lib/python3.11/site-packages/flask/sansio/__pycache__/scaffold.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e0c131c18514988723caeb50fefac9d7b49eb47 GIT binary patch literal 31837 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 RBDsTM&vweZM!+Q8{|B>Na?Ah# 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..21a79ba --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/sansio/app.py @@ -0,0 +1,968 @@ +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, + ): + 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 + + # 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 _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(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: + 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..5355700 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,805 @@ +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 + +import click +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 ..cli import AppGroup +from ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +# 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 + """ + + 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 + + #: 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: click.Group = AppGroup() + + #: 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 _path_is_relative_to(path: pathlib.PurePath, base: str) -> bool: + # Path.is_relative_to doesn't exist until Python 3.9 + try: + path.relative_to(base) + return True + except ValueError: + return False + + +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 _path_is_relative_to(package_path, 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 _path_is_relative_to(pathlib.PurePath(package_path), 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..bb753eb --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/sessions.py @@ -0,0 +1,371 @@ +from __future__ import annotations + +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 + + +# TODO generic when Python > 3.8 +class SessionMixin(MutableMapping): # type: ignore[type-arg] + """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 + + +# TODO generic when Python > 3.8 +class SecureCookieSession(CallbackDict, SessionMixin): # type: ignore[type-arg] + """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: t.Any = 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_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() + + +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(hashlib.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 + signer_kwargs = dict( + key_derivation=self.key_derivation, digest_method=self.digest_method + ) + return URLSafeTimedSerializer( + app.secret_key, + salt=self.salt, + serializer=self.serializer, + signer_kwargs=signer_kwargs, + ) + + 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) + 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, + 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 + response.set_cookie( + name, + val, # type: ignore + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + 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..a27b7c8 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/testing.py @@ -0,0 +1,298 @@ +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: + sep = b"?" if isinstance(url.query, bytes) else "?" + path += sep + 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..cf6d4ae --- /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, + t.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, t.List[str], t.Tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[t.Tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + t.Tuple[ResponseValue, HeadersValue], + t.Tuple[ResponseValue, int], + t.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[[], t.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[[], t.Dict[str, t.Any]], + t.Callable[[], t.Awaitable[t.Dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, t.Dict[str, t.Any]], None] +URLValuePreprocessorCallable = t.Callable[ + [t.Optional[str], t.Optional[t.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..794fdc0 --- /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[[F], F]]] = [] + + #: 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) + + 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..c1eca80 --- /dev/null +++ b/venv/lib/python3.11/site-packages/flask/wrappers.py @@ -0,0 +1,174 @@ +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 + + @property + def max_content_length(self) -> int | None: # type: ignore[override] + """Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" + if current_app: + return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] + else: + return None + + @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 + + 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 e: + if current_app and current_app.debug: + raise + + raise BadRequest() from e + + +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..c232cc9d118d90dd2547fcd083492d8ebef44058 GIT binary patch literal 2044 zcmZ{k&2Jk;6u@Wwv0i_y?Ko+^8l~HSeWZbNg1z#Fxfn`G$ zECc6^oZy_JxOpQlSOG2=1;KgXqEQrF04^CN!9`%zPz9HO%SKtS>QvmSQ59TvCfu4) z6I=nFG$sXCfv1cq!4u9UciNa1TmzmlW&}?tpOtebm!i+@Vdn; zz&zj`VqrqTD1h;aHE?_jgH-}+)9!c{>ro!G3ie&wB?;fDar=JPri8y&*d)}p9Q%QY zsowc`?Y%Xp<5Qb$yU?v}_#Qdyka-L-w!*{X#OuNpFw5GxzTrU3L^*YOX4Z* zr}k1$Muj+j`Q(YyOn&9TnP0L`A>uRmpEL>WNuOuN))PMCxrXJZkkzx(%r+5IUk%zr z$=)xeMs6c6n&vK{0n~$OQl8m^@9%CCt$xN`*DS`U-Rd!-*@1>hmy)){2-YkQYkk{s zv=-4Qas6HJ*`D?x3)U^KL#W>iv>VNvP3>Mlv@Iek0p4e%%?nWTsaCh$u1}d`x0)_t z7KW;7j`F#-WU~N|<197m5ISH`Yt2KRC$AJZ*!GS?c8L?0&JJ$m;@bJZvC_AwXM3F> z&Txur>!YPWGM}Av#mYF1I5)~8F0YN3f16UDHqvw&=8yBIGf)lefFG5nX~$pd+rCTm zuHSQr4qp%*bYZXbfcfnmt3#H9f!DTL(AV$xbv2R0+iU069p3-q(=)=ks)Y-XCx?tq_c2euS)hm*Yq$<6XC zDX1?{lq){mf00`Va|@AjH5^N%%si~{-+@y7R{cgDrc&w$(myg%uS7Gm!y?L0|Apjy z;cu>nLX}Zr{!y6yZt8hq@nvB#%q$+ktf-L@8%Jk= zDNlyZaqmK0FwLzVza=11zKgNU232rxkC=bRY5C!NR_Jz?#?oPZ_pZdOmc_PqmCKC9YLqK?-Eyh2Y*7e z!MP6VSh?l;7|!@@x&kKu=z;+BFfB<^gqFgj9H3e_mIJgBCM8Om&>Nv;7A7S^ z^)M+BYJ^FN&~liR2)!95$n$!L5^_=G^RwRyQ9>g0ewdV@T$Zj3 K(f=rMDE|VH_e6&P 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..2e8ea2d58bb518cf879c1a9156f9d6d1afc8cd59 GIT binary patch literal 1421 zcmZ`&&ub(_6t3!DX=f%GH|)W^NMls!Wp_I390Uo13M+UR4|`Asp{ePr%yiP-)mGJH zm^Dbi9L0-=>~RkgSMrB=?MT4bAOysNw^`z8PQL2SjGK*CSHF7ieXpy&_xjb3tE&wJ z+(%NgW2V zZ-al8Hg5PG+Jqz5%2xOhPjeEfPab{Rd;HF4g5)_99ua(;QEx}`%u6{PC(KhLqCBZY zoJ(&qiWQUa8S9iQIhiJ$(0LO;Z{HhC0V*BA)L3M5TXjCjrV&(aIdl^6;>)|B93k}r zwzJgt(J|;JOB=}Io^O2_&coov{$xRCdYz>L`HG^uxv<{ld5jgH|F@>9KYwA+N&trCgVg2 z;Eqb0j?)|>L>nyeDhR31@I0}q9j}3SsdUu`YdY{Dhy!%tuKnuX`Nh5Sr1R{pQ+M;s z-7MVA^QHIRv&O00J#)K-+x@*NbGK;wFrU6%uZ8OiyS3vkq%}whS z!OC0Xw=}*|x?z}+l!am02*dhnfZhtjFUKUgLRP|%@<_X-zQ$3?poeJH8&#G+p^8ME zw*Iw33r$6S4&q?>oLgIkwRK_Nni<%BbA}e;xrv|I2vpZq<3eFE#+smroK9GZSNc ij@~G)&kJp%i 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..c787252e66ea4494579c087369a7087dbc881bd7 GIT binary patch literal 3000 zcma(TOKcm*b%sl>Xs%YG#OPO>@kVkjFbTz4RunaL3`mIu7ieXqc9NEfL##L>ippx2 zogGRRBc*H+6hSXl5gQR&1kuTLkrc?$$NJPO*I2;90s;)=+$X2psz*(*gw z_VHp|_KBiO6cV?(R+GgfMyC)tP0o;>&l1H`Bumnt#fvHE`=HmTveJEg+}{w4^k*Z| z|CO@ab3AVEN#-s{^bLGrEB3|^jjyDS$K-_$dLQju=|83xGr+B`yl^}w13(=(9^H+> z&hUk;I7nV3!yxGpIZJ*7{V<7LM>*q(Am?zPnYQh4lUE(vU3ek{g2}Eqle}$m^J${a zm+~`#>T*^s^8mX~H9(C`V{wC1H%L;u?2xKm2^5$PRLYpc+(2cN*O?t8Bv)ApC6Q2g z1jhLALqNVn{KNtXZ6bamH9}D>*x)AGZKFQhaT9OGqP$zM6KIGRa!Qb@x>eidrd_5? zgGC^skeKEamV_Y_p~Hm#Tp^@k7*GFLSaw!vq2|;rS^#FYQR9>pT<(-VHY+smZrEjW z5oqh{>jgsBsO8jFsm%+^eAOx}I?l(X3biRSxx)%;)LtuC)x|<>gD*Sw#fb|S3T~Ct ze9e@*xrHisiD_3TbLy@*PFi!Kwh^S(O`Dgb0a*rQ6VkgA0GjAODoXZmzjWui*EQmI zjT|7H7~kvG|9tgNSGRw?v*vZ5_q)%3jvs5?&8vs70<;$Xvn%B`YYQ)gp0EMw^h7lJ zwh(Xg;mV00Hc^ysw~b4j8#aQYT;Q8nHT*X}UmNl!pa+LJiov0aa)V>J}I09JQ5`y*gK3M`MVKd^l=cR@88?6g!95z!v5w zbqyh+Mm@TT{}3ZxTliDFj@QvGRf5aeA&lYlBVMHhvwb?MR zM`9urG&pr*qeicYQWm7%Gp%}vGhs?NQ^ZMtsVlO;=!lhY1NLJeoq^B&9e|Tqxi@rw zxTVi|`kb%NHRt!@sn5wBcW3%9pWOar+uD7{8$9pzjC=9%=KMiiNnG0R9q@a{@2OsI z!S5}!l7%1ky9e$xTH2_{_)E{ge$PN_@S@i<<@Ze8f2o!H*$>bT6ySm06_)vDW)`Cd zxNmk`dC;Gp9aSETCID|J`O=##3k;3e<#!rq`NUhMWr^zc!3WarH(xb)y#~Xo&2Qce z6uZ6}D1b*oS%ejQ_;4PO&QOj9%5HlB0`9OquRtuw3=3|&%;=ZcGdqd?LHSxN@JW%MZvP?mlz_J|6JPUML6iOE5oQk&xsaD`pWqq(? zkS-k+anq_Tn~M~7ydLf>qiTApbaYT$T*&NYu_j(NUEr(Ra!OQt8B5Z<|3K1c@`8Ap zytL{NcqLqBv%n-G+Z_c6iHGqX8f``YkCEP#zrE)m{VjC#e~gA((f>gbU3wcIC@R(u z&~re40{`>?ML{}+p*}>x88npj2VZVwF5jE~_LtCw|3{fC4>MQ(Rq-+lerBPC(vQ>G zZS}UkL%j5upB`)Kd+Ds79u@uIHomR4hGy>P{Wli8^ffuZy|o I0%^nl0*y7W&Hw-a literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/itsdangerous/__pycache__/exc.cpython-311.pyc b/venv/lib/python3.11/site-packages/itsdangerous/__pycache__/exc.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a45f9031251c23dcf909d8fa89cce65943d80d4b GIT binary patch literal 4871 zcmcIn-D@1z6~D7PyF2@#kNTr>uw##sI_lciPTV>q2-CD7As-YGVnfTeFuK}%rJZJW zW_$0fWC=YeV5kayFofbh=E=nv`fv0tY=R+TAP~q?-&RP0pr@X5XJ>ZyBXU*J*_|_Y z?zwY6&i(z)Irkq^QzZh|r!)Ur|D;05xA+oYxu~EWeh!64gb}8>q@~q04a*rfQ_sRP z>*_7Nu4^Pi-X%=GPgsuU9%l)83U_qX^GcToU4iFEbOog|Kv(325uKrQCD4_*F`_Ff zT?KSgW8amOZW?qmW8;-s<_@XO{u`%O)xt9MJU^g;<9l)$-VH_r9yl%D=ucif`b*Ic zZ@}wcz!;p=HAd*`1G@d`N7Rv= zna-NIN|^}*QPW>DskdcHUj*hRl_vKZe#Z;A;H+leZ939~f6(Och2$j@t~Fnn)OAgM zuff}D+MuU_`Fxakg!C`7-vgM=Bu@vuPIenXmKg& zIuEll5RFV~(YR)~wZq>-;cwa_5@-YMV<9bzYAFmi`H z(Uz;(Fef{0E<(e$9nT4DTNI!dsMjTT*VIc`wC#pVrL=8{6En@-<4>%n-{Mx=@3`Co z!-=hSz?mfjzwt4wXi;u?4Y~@t&CN}V@eS_!?H2a}s~NOhYt{EZw%57G1r2;*ZE$bH za-CJHy%jWl@0YckH!bM|e6dYcZ_;uC$zlUrVEtNqO8{la_H2KHYw`4_p;o>E;`?3l zwK4VA!h^zB#)U793xA*c!kB+%%y*6X{kh9~`h&_I{0^Zd3G;#n9pN<+b3rAR)fUV` z;St#(e}ZRp-5~;*Th$_4X<`cABz|Cu8IWNCEENdb-kupuPgR`3hWPC+*`GQ4V5e(b z6xe??qq-7CRQ?G(qH+N@#-lB6+hNJJTRsDWL%Cwxf9_DXuYvKH-+;YCn~1X@!m0kA zHMr~A_7hDg!{8i$t>!55*c1isxBLSLuvq--W%QiUBPc4F+?5{rAz^5_OFi;jp%$q| zYrsIsrAH<05I1a$+6F5sau@DT)pbSc9FV#cR=}utoOO@Fp7HIg17=fG#?>bCxirDM zm@OJKnziMDeZxYVZn-{X$CaS=8*l(S=Cbec20}Z&u&g%!N912-lz$P3vZ4%wMLTy1 zN>yFKDVi@Q z^z$Sy&cQ>RNAXh>b0`$lE?`NGm_pV?tVDs0<$EAtD)Db$x4OF3(~aC>kDOLSQ^l?) z!{{1lMqyMWMZ!v~te{jJf>I?!_i+~j&HzrUX*gjlT14;9Qpm!%;B8RXNks`jUT0PL zNafifvMi~$rIqv^t<;n@g~frD!!iax8v)GO@k|^EV{rDF0_!6L%L<%zDEx21VJGt# zLc!A{96)%;J|CVh!Fbi&C_J$?!YC#!fYBk4zA$Rx1gKSLEiDj$j_)d@IGy&@pDlc0 zTzh6*>l)X3=g6gnJ^h(+p{xFVhq=65%};`>Q1f{iCv^qIC_3k{62;HpmUls<(Ampm z(C?v`Ci7SK7q0h;v$=&HIjxA0io*;c6zcuP<-cJ+ksSMTci;= zaBzrC8PHZ6vlQQDTwpHZnJX(Tde4R!ys{EyF$#0gW`I%5e3l@JDs&FPKSn4xp$VLS zLZW41j1%axmADNBc^O1Z@m-QKqp~H6=u`Y^$Rd4UPtNX;yTINut0?xChS)n576DuD zaSBV{{^zKXfU-@cLi6lk1*ouG*+qUs^pn-fyMU)(yu1>~dt!)aeQ>yAfVn+xHKXm15Z}!M(MZ^*uX);Srl_-_KrXNPR z4!s4gC(V(54wPa?pAc{ca)CRF4R~C_15m$l>`5?r0)8a@H#Z)h=JlN#iQ@sz^23@Ic6Z+wtICK@!VQ}tJeJC3GjYda+n>1NRINrL6 zbHgVL35O9>_?`)eyCoU~VreDrDq{OPIK6Qj%X9rM7_{E`_#IFF$KXg=@NU50ocydt3l;_b0qr5=zN4Vv0K@8C+ zkMuz?n?uf=Rz#e^?yD6%B&~JuU;w8f+?g;RY_$Opp%w_VOIS>tX>R 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..8e88a0c5c69e07ae10ad6f8414200904f0f90465 GIT binary patch literal 15777 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 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..dc2d4a4c018d5f8ff6f8a47577e42a8e4741b733 GIT binary patch literal 12530 zcmcIqTWlLwdY<7;6t6NRS(YWoBg+?2v8gzAoP>6g^;&UaCsxwPPItANQX|etV#3?b z3@wYG7uvuN+`tQaw*l-$Hz*6Vse=u$ekh84+_&x{DX=v`z=eQC9`;RvQy?&kw%>ow za5y8$-Yw9MsKdiE=klNb{O9{G=lo+h91!sQb@X4Besf3={y;xEkC$h}N1Mpp5fniY zvqDas6Gh6qvaXza&SU1ib6!^FoAa^no;knbRy^6>TwpGMI&Q^_d~hzv@;>B4b0L=R zK|VYeW_f=$l8eqoMZqP!At=2!1SRmfOAvmIfBww%u{S}y38{UbyYUYH=DS_Wh%&0g zZg}TntX4m24Q#8`uk2Iy-0;i|usXx2vvNYO6gK|D!Fk~ZB$m=tI z6nSA^YC+c3Qzuh$wzw=Ws0J#A%_2oj7ZlZ2pysLI3$Yzok@H4sVbxG|ybgU=R%SCx zdD$pwYMM`ir{;XcM+flxj-U#2q9V+>6mib21Qj2s_b4Io#{;ehKx??&M;&GIOJ}o7 z1ubJN=gLd7rG<1>)^$~vawXl6GPz<_&8c}qO6F8!IXSyOoudDMh`iW(!4P;MB5_%T6s63Lm9R-W0Sc5Oj4an^~ADt{TgQ z{E5Wz<5POZP>&U5)|)<+F?2=FFR5Cgq~p~RxSA-gw!@BfC_l4xB@>SK12lmMk~QJ0 z$XFvX-i(ab{o{{NBDCG;we106*|diW%%=z6jP;k1xg*$F|Dm-E6?a9bSsSg>l)fus z#pT>0&R-Bfv3%)$Rm&`9AZ)Z^e0{nil#`A0viVNER#emAGm{>Nq;Y|wqBs_9IVY#v zk#r$flr=S_WR_Ij&~}5KxJM%{bQe_HgP%IhnA&QC$h7;e5WRHq*E!z z3~e78ejzYY*vz#MbxaA9^|z5(v;H<+F0X%6pv3R;9;BQ-@q4^)ikrgIQa%uMpT@uS zSctV3MOzTdZz5I?1f{nfo+;$jE=^K!93c2WQD7GEW2y;d8Y4wbhQn z!0)FE`6GrTr_-vgOY`%~vc3#ZOz6w<@%eeFls7V2Nu#fvnvl+4cz0G>C}pw=bdx^aE@}h~ zI?dO_m_RBkmjN+&s~tu01idF{0)7O9Q2)&{cYTfE{$_B0-Ls!9L>e!xhq#PKd~_aZ zch6jboi*on393i+Iyns6%BA)w?lY(l{U64@^1{xFC_z{Py^04b5N(IwymaTt_Hicf&Y1-68PiRDcd(h;giMT0ZO+lGyhdBb9zteV2L3vC@d~}#iq#~~MRD=(a z=g)N!8bnB0f}#ks!WZI9+@(#Sg7zE|UZ?IlFb+J-n4s(NYT;PI-b>EBytAHEHk3DCvqZBRfKFPq2$GEbCys6$N8V!)T8 z(+<7vuDEOF+M*lVV6nzOC21_XnEC&($N-jmUH}GF^28vTl_>DgU%`vr_ku zaMls}V3lZrn4EAd3+#kt?T}99a+*sH+Zk-7+tF0YW=lhXouJ+bOto=Jy2zKHpOi3x zSVCsa_Sf>9tb0yw284sp)y~`xG{#Ri$4}Qi!*vf*`ZPSJH$5Kj^Q6kQB_Wr0loa2N z38#TZZU=NV4ds%8mHGHZpr%xjn30QbScU1t1p`(wtivDR-3QwWS=A372eTR7_yPan zfLKe^G>qjGwTfU^!X*fX2Nld`af=$+$+6)U0>jehRB8Jjg%&W~0QWmn?4wy4`T@Z-Q4;s9B3ua?JCIr$@% z7^(|h@Uh5@tM2&FLj@QvG<7))G=cv+aNC4VC!5_Ol`I-I?uiwo!dY*0eJWG0Y;$h$3 zyU9l1;b!0Adh|%$e`JGER!f4MMljLDFHeF|ltw?+V`6~#sD`5dHNJa*>|UU~k7m(p z{V4~PL&|R8eyr`hcYLX!VLZ#d5_$j zW~Licx8w*g*Gz&UC97aTMXU5O`9Mk{!0KEk_m1r|=FRELOnEOrrAr#Ldm$%rdqpZN z!kS?F2xbK7eX}aeL)HDkWizC+DY7m{yC1KF`P@M>Uft zqm?_(@SFCihq1{3oPy zuy2Toj23c=Xn)a&wD*omg{%T+idY3DgB%tVJ(Y^gs3NagGXoyn7U~cJ(vs5a*9=W& zi-k7W*9)1vD$%G|pDw9bB)qn9(xSvNLv*t1c3>*2*%?wTCc$K4gaM8s&ay%>#Q27Z zGc%vhp5hJ;YB7zJ0w3@yTY#kWW?_YqL`B?)BudEop$RW)5Vh`dSk%%xYgwds3%Z^G zhv!D$Ofr3uXsY*sR z2(lnwG#dw7EEh8=ot2U-K$e`J<&t1o>r=m5RwJiwG)LWrem9^IJ%Mx~@m3KZpG_ z&vyr=X7z%VW8nJ z#CE(?F7aXqVF1u}>f7 zq-~fja?de-8=s^Vz_*PAb9~+E=*ff-3UbSpypG3V$4=E=M_GIK&YSQN1pw^9y9CLL zsy!l)CNaaz4DA)_z(Z=~aSXG!8H*GqfNi1{9|vtO+7aiB9|!nLs?DtI$06pIqa)Tq zueA=3hqj8VSto6?1<8%!uFQ8p$C%?z?j&8Oma8hof{nly+B3Ljc|gRDRE zxrz{&5$ybeo4RGJkKsK1q|Y&m%Q?z*SKg(#uDi&|O2HE0PsPK0N^6GKJrxh$TO(Jz z>^&KN?78l(c=4VcZcstRw>Dsqe_=kL-+H%Yd|$j7`$k334O&r}UwFQYnSUMq{ojrHqf|OMaU>9^VkO6Ow zGOcsuSn8D{JbG^%CZW9r%Hm;WzP5v1rK@W+f9)MgXdT;u_em|XFt~P!N-t9K7nE48 zH*>QziVVklxD!qWC$G+WV%3@7N0nGqi}n&89;G5Dt{mlC!g9-hLRJ4639RZ-A^y^D z1C5Du&53j5lJ9xA_h4=Ims7u*s(NnvH-gcdFa7J#k$R9m4`ZW_PpHO^K$jV#XUk5aHlT#GnZE_t>yDG{IBNf{qSh^o{;32&sr=lsHGMS%6}1<@B(&9)37z z^q4eW{J)`5@e+;yFO>RBN-r3s-pr>9iWIW@(Bk2jJly ze`jfxEQwP5CY`Pd!Wl+acyK=K>>uZb0r@|n?P%*rJoqFbhX_NK`-RLM;I=P?2pHizw8|w9TC% zR3o5+4peib^mc$a+xUOV;-&7n)k_^aZCEe@{;>+R*(GO2n}aO2ecS=lF5rhwQmiwJ zjYU?0d#9+5Cl6Dryzff>qkLh7A12#Yk}nLDEI}pLtE33qqS5x?7{cIzCZ-mdW~DeZ z>t1`2s`*Mq1x`r2_ws5{WePa%wrSUwQO9wl)DCd&QgF;d;BFCVQeA><1A+Gnq22Z1 zzSi)*=5YMpf#&eB>c#5CuZG8K7aPM<&Ecu)Md;LK@R{1gdT_EHoP5|n@ad_~4%G%8 zjGb5?J8^&dpDz3^&^URqG4@t-?5zi5@2!u$*BHCp9J}1;ztZf#QV(5eg?BZ>Qth4f z@QHf(1nb~o-{5WI!BBjCD1PtYm+||V#^h_in`}(J-59#m9J=&i=<@o|<;Kwa&7t?d zcDn|kypbTz3gzt+A~EXj{Caq@9-e#{+x_Xp-6W4X$EF*x>1J%Ydaf0U-n#h7#oNZG ztBufDGc;BYjkWrB-%0)=`SUZMo~eiSn^c+IwEFkeL;Jppjnqd^H)3a+F;qFj6?YWu za-2|*l3+^dSI9iw8pdgbPy?s8KTb6O2(-ae&8Eh>En&loTY%GTST-uaa*Krxn?Wp3 z{yA44%qtIGE}07$l9_Nkm`*CLb6P;G;76eBbekAKd&+i>IbiC0$1%YJ)YH!)!8HR! zKVN9{jWzqms@_&4cB}A7p%K~NjO@or0ge#z4H)?mz zp@?htFg83p07yC5F^%x!->J$JlC2zy4nTyjHDDthd~o38`hk=8uQU#vZXP(@h@P(d zPjd-nr~jnP(ssciq+(+FU&!1+%-0cr-|i^w8h0EO927L%$ND~;u32G4xaR)8up&BK zt!?&|-AVzMXLOxV!x9`}Qj(v;aKbN2V}o1MZCRopAm#u2~TK+P$w|qc|+$zHDvVehn9Q zG(?9ul6SWXU7WySJUe$}yM(O?bAITYP^Zb#Rx$SqRWCC^g1+Iw*6!t!KTw0eLjrvE zxO;~m#`f3Tjo86v>|pg=_1w1)qkC|Y&^z2sTK#)&zi|77O*cxv{q|cNJ?t9kZnLlU z9;lscj-P1kJ=xrQ5-w0LPOFeqFScU4?@aw-sy5k(9c#vpRnKii`)~gEK{T-*P2AJ( zzy8}3jp%F5=xZ1$JlYx>xozAwFi3b5DBL$#E$QUgejJSnzX(X~zZE4nPU}cFDk;WD z2Wk=rm^glm%%9w*woO_QuZr3pyXYy7P5d|T@ITvveTWQ*Pe4&y&x+fLr$2 z(-K|~Ydt{VEiE*dt}rBRqO5o-Zcya?%w2JP>2vlEqq3(we5HHR(Fp-?04cj?3Q{== z@2rF)30OOfi5iho4iH#yiA4?TE(^N~g}Z7!MR_$_kQInv7lX)!!RVh;D+Gj-G7ex|OO zjo{H{@F){)NOkq?uOfTvBd^|bBjKOld+U*zMr5WLnW_8v%^HWC5xbb2QGkJ94^V^L z_Ghbu2*3bTJOKo;${i2{nB?EdBO;9D$&g*<&;?BV`N}1vj`E$KzpRy1#5^;LmI+Ou zLz{&!s(KA)Dij9A!t1=}t{r;$JXA>zGtg*BJ8Fei(V4!9R}r)%5lUy;Jm7Vjau+F~s8!pK3$M6a zW~_3WnQkC6KvO9p#OG^RpxihmLzK`3L+#B@LVPrB^EIp%|J!tp(?vT<-WQ*GPaz_V zKVSFkt$U91Ps4MZZZ;%aBl}y2;;qAztz*YGqes0jYzjLhKNJODWYguLYkZyLYd6Yn ze2LHU(!AaeL2f3eF@D^$u;v%go7o!PY%9Jog)Oji0S&8qa8Vo6b686=dpG{v_r2C#br(d)3Z|rX+pNN}=+mrgh!LO=GejJEvc>@^7B-mdV`z0P#8B A>i_@% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.11/site-packages/itsdangerous/__pycache__/timed.cpython-311.pyc b/venv/lib/python3.11/site-packages/itsdangerous/__pycache__/timed.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..288aab44022c090982b4f8a83a1d8731541159e6 GIT binary patch literal 9797 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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..763f679437a6ae257043d609972e41bb18e03ed3 GIT binary patch literal 4182 zcmbVPU2Gf25#Hn7@&8AnerVNJe5qtu1Z=X79k)>2CjP121ho>x35>D`PDkEKqIJAu z_l~ATP_0q8ErX^-in^!*xPVX;t^@bM4@J?(xIj@9=mTX42yuV_14SP4Mpu3?{M4B} z{)m$M6R(bQv%531yR$RjjeZ}Cg$cA@CjPeg_Yfif#7?&bJVx057cjpjI?)A#l!Tlh zAn!ALIg!7moTQ7oWXL6d&JS~>F`8%SLC)x$X)n(EtlkSF_4SX!dldUFnhVtLJ` zCr_w4Em%6;F+k1EK=_QNzoo4hmZrn>kowj+&CxDVR@97QjWQSu5A+i66iZa^4;8#~ zc(ijYVf#Gve*)J-Nlws7&i5`{Q%MROclDm#i}DK(>*4=d0L;3`IKTXB}CVmqv8F5-MiTc)UIFImi?OeroXCM|%R z##S=Q>s^C}ZE-7}hZWDEJ5AXZ^fU)e6*N<^;RMEtlBY`9&E_?PMa$%0iJ#u<-Af?<}8!C z{^cr4xPC^R3Ns5n@A3%7kPJUi5w;hg_bUMsOjwoc!g@z!@TL21gVbHranF(@P3MrU^@}2Aoc^qj6oX2mau{4ST)Y-7l#J ze(2N5YT)~Us!%1@#P5)*P?y;(tOl^rZCCJ2yw&~Bv2Ni1Th~XNSa%&lZUcL_*S*p^ zN8P_D)WzQlZ<8XaOTQC-EJrs@J{WOvsT5>707O-6I@>U^5E*+HN;Ut ztJqYr78D3BdaXdq2n7%taf=lfi>79%lrf9dPWR1W=qqS!N8tAjE?A86S)FGBBt>T~ z9fWvuH0IctXv`10bVJ|lF3Ez}m(aEw?i+VyyHcjijUu$DT}vTXvZ=AahCqkMCQBkW zhGdf4xnf(UD^NG2ss%%{ZB@1LGBIJXU4Q!H?2=WY*)lkZW+Cm^O4*@$)^@DIvbIQ% z+AC&3%fno?TFvV8DmAQfiJDG!$tfAxyk#w`i`1k{b1as`{eDhUhhn}7v|Cprtnkbwn;rhis>zxqLSGcmP(u9=v+&kG}gR}NgaLw(+ zN%E)g>6Cb%Bu^*B`$-x3$W6{+ z$7I;Ko3En!RUnWITZvJOkxvs-4T>*KPo+l9BD?5v_>Wy=UNAp#>LN)2iK*IiSb5!8&)Riu!ldxz~%!rkb` zI>=X`hM}ry!E-sr?rWa2@k7Iq;EwH|0s&|C|JpuL4z>xBFgf=1rZnD^PI=FUbPAGl zdZrzEL4Ku8{x^9|h|8%q`2vJtPV?Orfa$eP>IvJ3_x-{U%R*k)itg|pD6M^R*<#DK zVichwo8@1F+4)Sr44hZ;6-UA7vf(4BD+sza)PqpO@yd!9RtVSK>aGB_a?y71^9J8d zEc+^D_(pYTviH88iNuV#yuf!Ml;GwTAn(JW-C>=7<|vqA65^~&mTeNC@|a( z@EPE}s&4LMiDlrxEQ{nTNR9#dn0Q{|sq-?9BKa2lwlRO7d6oP=k$9@8@C6;*t)q8U z@U_1_%geij{+p}0f8g?XiTnJn=4S9tp3~LrB)EhjzU*-BEOwE+iOkn}lQ@(f!<1d9 zKoJZn%S0G*{mx1m!ow9D4>n~L>k*!}ZjjgbFv}|-4xz3Hl@~97JoLayh2cN1uI%9d zNeuDa6`_*n8NsiaZ)ev&p9W8P(D4m+7Bnzf?DIg|q96z@^5y2>^N=K)-KRw&*ZJQ= za7IP+pRjM__@ p`!e^!e?I=l#3P)1+?R;&mF4=)$>aCbPcCh~{Q7Q 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.5.dist-info/INSTALLER b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/LICENSE.txt b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/LICENSE.txt new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.5.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.5.dist-info/METADATA b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/METADATA new file mode 100644 index 0000000..6d0348d --- /dev/null +++ b/venv/lib/python3.11/site-packages/jinja2-3.1.5.dist-info/METADATA @@ -0,0 +1,75 @@ +Metadata-Version: 2.3 +Name: Jinja2 +Version: 3.1.5 +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 + +```jinja +{% extends "base.html" %} +{% block title %}Members{% endblock %} +{% block content %} +