From 4ebdbfd972acf35ba3fb531ac97edef622646fd1 Mon Sep 17 00:00:00 2001 From: leonvita91 Date: Sat, 10 Sep 2022 23:26:07 +0100 Subject: [PATCH] add flask-app --- bin/Activate.ps1 | 247 + bin/activate | 69 + bin/activate.csh | 26 + bin/activate.fish | 66 + bin/flask | 8 + bin/pip | 8 + bin/pip3 | 8 + bin/pip3.10 | 8 + bin/python | 1 + bin/python3 | 1 + bin/python3.10 | 1 + f.py | 11 + .../Flask-2.2.2.dist-info/INSTALLER | 1 + .../Flask-2.2.2.dist-info/LICENSE.rst | 28 + .../Flask-2.2.2.dist-info/METADATA | 123 + .../Flask-2.2.2.dist-info/RECORD | 54 + .../Flask-2.2.2.dist-info/REQUESTED | 0 .../site-packages/Flask-2.2.2.dist-info/WHEEL | 5 + .../Flask-2.2.2.dist-info/entry_points.txt | 2 + .../Flask-2.2.2.dist-info/top_level.txt | 1 + .../Jinja2-3.1.2.dist-info/INSTALLER | 1 + .../Jinja2-3.1.2.dist-info/LICENSE.rst | 28 + .../Jinja2-3.1.2.dist-info/METADATA | 113 + .../Jinja2-3.1.2.dist-info/RECORD | 58 + .../Jinja2-3.1.2.dist-info/WHEEL | 5 + .../Jinja2-3.1.2.dist-info/entry_points.txt | 2 + .../Jinja2-3.1.2.dist-info/top_level.txt | 1 + .../MarkupSafe-2.1.1.dist-info/INSTALLER | 1 + .../MarkupSafe-2.1.1.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.1.dist-info/METADATA | 101 + .../MarkupSafe-2.1.1.dist-info/RECORD | 14 + .../MarkupSafe-2.1.1.dist-info/WHEEL | 5 + .../MarkupSafe-2.1.1.dist-info/top_level.txt | 1 + .../Werkzeug-2.2.2.dist-info/INSTALLER | 1 + .../Werkzeug-2.2.2.dist-info/LICENSE.rst | 28 + .../Werkzeug-2.2.2.dist-info/METADATA | 126 + .../Werkzeug-2.2.2.dist-info/RECORD | 98 + .../Werkzeug-2.2.2.dist-info/WHEEL | 5 + .../Werkzeug-2.2.2.dist-info/top_level.txt | 1 + .../site-packages/_distutils_hack/__init__.py | 222 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7595 bytes .../__pycache__/override.cpython-310.pyc | Bin 0 -> 242 bytes .../site-packages/_distutils_hack/override.py | 1 + .../click-8.1.3.dist-info/INSTALLER | 1 + .../click-8.1.3.dist-info/LICENSE.rst | 28 + .../click-8.1.3.dist-info/METADATA | 111 + .../click-8.1.3.dist-info/RECORD | 39 + .../site-packages/click-8.1.3.dist-info/WHEEL | 5 + .../click-8.1.3.dist-info/top_level.txt | 1 + .../site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2625 bytes .../click/__pycache__/_compat.cpython-310.pyc | Bin 0 -> 15760 bytes .../__pycache__/_termui_impl.cpython-310.pyc | Bin 0 -> 16084 bytes .../__pycache__/_textwrap.cpython-310.pyc | Bin 0 -> 1559 bytes .../__pycache__/_winconsole.cpython-310.pyc | Bin 0 -> 7677 bytes .../click/__pycache__/core.cpython-310.pyc | Bin 0 -> 90225 bytes .../__pycache__/decorators.cpython-310.pyc | Bin 0 -> 15619 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10207 bytes .../__pycache__/formatting.cpython-310.pyc | Bin 0 -> 9472 bytes .../click/__pycache__/globals.cpython-310.pyc | Bin 0 -> 2444 bytes .../click/__pycache__/parser.cpython-310.pyc | Bin 0 -> 13687 bytes .../shell_completion.cpython-310.pyc | Bin 0 -> 16588 bytes .../click/__pycache__/termui.cpython-310.pyc | Bin 0 -> 26224 bytes .../click/__pycache__/testing.cpython-310.pyc | Bin 0 -> 15202 bytes .../click/__pycache__/types.cpython-310.pyc | Bin 0 -> 33246 bytes .../click/__pycache__/utils.cpython-310.pyc | Bin 0 -> 17632 bytes lib/python3.10/site-packages/click/_compat.py | 626 ++ .../site-packages/click/_termui_impl.py | 717 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + lib/python3.10/site-packages/click/core.py | 2998 ++++++ .../site-packages/click/decorators.py | 497 + .../site-packages/click/exceptions.py | 287 + .../site-packages/click/formatting.py | 301 + lib/python3.10/site-packages/click/globals.py | 68 + lib/python3.10/site-packages/click/parser.py | 529 + lib/python3.10/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 580 ++ lib/python3.10/site-packages/click/termui.py | 787 ++ lib/python3.10/site-packages/click/testing.py | 479 + lib/python3.10/site-packages/click/types.py | 1073 +++ lib/python3.10/site-packages/click/utils.py | 580 ++ .../site-packages/distutils-precedence.pth | 1 + .../site-packages/flask/__init__.py | 71 + .../site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2393 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 221 bytes .../flask/__pycache__/app.cpython-310.pyc | Bin 0 -> 74881 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 24187 bytes .../flask/__pycache__/cli.cpython-310.pyc | Bin 0 -> 26883 bytes .../flask/__pycache__/config.cpython-310.pyc | Bin 0 -> 12437 bytes .../flask/__pycache__/ctx.cpython-310.pyc | Bin 0 -> 14468 bytes .../__pycache__/debughelpers.cpython-310.pyc | Bin 0 -> 5935 bytes .../flask/__pycache__/globals.cpython-310.pyc | Bin 0 -> 3311 bytes .../flask/__pycache__/helpers.cpython-310.pyc | Bin 0 -> 24021 bytes .../flask/__pycache__/logging.cpython-310.pyc | Bin 0 -> 2461 bytes .../__pycache__/scaffold.cpython-310.pyc | Bin 0 -> 24711 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 13613 bytes .../flask/__pycache__/signals.cpython-310.pyc | Bin 0 -> 2400 bytes .../__pycache__/templating.cpython-310.pyc | Bin 0 -> 6964 bytes .../flask/__pycache__/testing.cpython-310.pyc | Bin 0 -> 9409 bytes .../flask/__pycache__/typing.cpython-310.pyc | Bin 0 -> 1684 bytes .../flask/__pycache__/views.cpython-310.pyc | Bin 0 -> 5398 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 5086 bytes lib/python3.10/site-packages/flask/app.py | 2548 +++++ .../site-packages/flask/blueprints.py | 706 ++ lib/python3.10/site-packages/flask/cli.py | 1051 ++ lib/python3.10/site-packages/flask/config.py | 337 + lib/python3.10/site-packages/flask/ctx.py | 438 + .../site-packages/flask/debughelpers.py | 158 + lib/python3.10/site-packages/flask/globals.py | 107 + lib/python3.10/site-packages/flask/helpers.py | 705 ++ .../site-packages/flask/json/__init__.py | 342 + .../json/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 11507 bytes .../json/__pycache__/provider.cpython-310.pyc | Bin 0 -> 9351 bytes .../json/__pycache__/tag.cpython-310.pyc | Bin 0 -> 10999 bytes .../site-packages/flask/json/provider.py | 310 + .../site-packages/flask/json/tag.py | 312 + lib/python3.10/site-packages/flask/logging.py | 74 + lib/python3.10/site-packages/flask/py.typed | 0 .../site-packages/flask/scaffold.py | 898 ++ .../site-packages/flask/sessions.py | 419 + lib/python3.10/site-packages/flask/signals.py | 56 + .../site-packages/flask/templating.py | 212 + lib/python3.10/site-packages/flask/testing.py | 286 + lib/python3.10/site-packages/flask/typing.py | 80 + lib/python3.10/site-packages/flask/views.py | 188 + .../site-packages/flask/wrappers.py | 171 + .../itsdangerous-2.1.2.dist-info/INSTALLER | 1 + .../itsdangerous-2.1.2.dist-info/LICENSE.rst | 28 + .../itsdangerous-2.1.2.dist-info/METADATA | 97 + .../itsdangerous-2.1.2.dist-info/RECORD | 23 + .../itsdangerous-2.1.2.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 874 bytes .../__pycache__/_json.cpython-310.pyc | Bin 0 -> 929 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1878 bytes .../__pycache__/exc.cpython-310.pyc | Bin 0 -> 3417 bytes .../__pycache__/serializer.cpython-310.pyc | Bin 0 -> 9701 bytes .../__pycache__/signer.cpython-310.pyc | Bin 0 -> 8469 bytes .../__pycache__/timed.cpython-310.pyc | Bin 0 -> 6483 bytes .../__pycache__/url_safe.cpython-310.pyc | Bin 0 -> 2702 bytes .../site-packages/itsdangerous/_json.py | 16 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 107 + .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 295 + .../site-packages/itsdangerous/signer.py | 257 + .../site-packages/itsdangerous/timed.py | 234 + .../site-packages/itsdangerous/url_safe.py | 80 + .../site-packages/jinja2/__init__.py | 37 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1610 bytes .../__pycache__/_identifier.cpython-310.pyc | Bin 0 -> 2085 bytes .../__pycache__/async_utils.cpython-310.pyc | Bin 0 -> 2722 bytes .../__pycache__/bccache.cpython-310.pyc | Bin 0 -> 13964 bytes .../__pycache__/compiler.cpython-310.pyc | Bin 0 -> 54567 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 1546 bytes .../jinja2/__pycache__/debug.cpython-310.pyc | Bin 0 -> 4002 bytes .../__pycache__/defaults.cpython-310.pyc | Bin 0 -> 1346 bytes .../__pycache__/environment.cpython-310.pyc | Bin 0 -> 53396 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5545 bytes .../jinja2/__pycache__/ext.cpython-310.pyc | Bin 0 -> 25709 bytes .../__pycache__/filters.cpython-310.pyc | Bin 0 -> 51199 bytes .../__pycache__/idtracking.cpython-310.pyc | Bin 0 -> 11097 bytes .../jinja2/__pycache__/lexer.cpython-310.pyc | Bin 0 -> 20449 bytes .../__pycache__/loaders.cpython-310.pyc | Bin 0 -> 20536 bytes .../jinja2/__pycache__/meta.cpython-310.pyc | Bin 0 -> 3826 bytes .../__pycache__/nativetypes.cpython-310.pyc | Bin 0 -> 5021 bytes .../jinja2/__pycache__/nodes.cpython-310.pyc | Bin 0 -> 40336 bytes .../__pycache__/optimizer.cpython-310.pyc | Bin 0 -> 1966 bytes .../jinja2/__pycache__/parser.cpython-310.pyc | Bin 0 -> 27697 bytes .../__pycache__/runtime.cpython-310.pyc | Bin 0 -> 32161 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 11980 bytes .../jinja2/__pycache__/tests.cpython-310.pyc | Bin 0 -> 6700 bytes .../jinja2/__pycache__/utils.cpython-310.pyc | Bin 0 -> 24523 bytes .../__pycache__/visitor.cpython-310.pyc | Bin 0 -> 3985 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../site-packages/jinja2/bccache.py | 406 + .../site-packages/jinja2/compiler.py | 1957 ++++ .../site-packages/jinja2/constants.py | 20 + lib/python3.10/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1667 ++++ .../site-packages/jinja2/exceptions.py | 166 + lib/python3.10/site-packages/jinja2/ext.py | 859 ++ .../site-packages/jinja2/filters.py | 1840 ++++ .../site-packages/jinja2/idtracking.py | 318 + lib/python3.10/site-packages/jinja2/lexer.py | 866 ++ .../site-packages/jinja2/loaders.py | 661 ++ lib/python3.10/site-packages/jinja2/meta.py | 111 + .../site-packages/jinja2/nativetypes.py | 130 + lib/python3.10/site-packages/jinja2/nodes.py | 1204 +++ .../site-packages/jinja2/optimizer.py | 47 + lib/python3.10/site-packages/jinja2/parser.py | 1032 ++ lib/python3.10/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1053 ++ .../site-packages/jinja2/sandbox.py | 428 + lib/python3.10/site-packages/jinja2/tests.py | 255 + lib/python3.10/site-packages/jinja2/utils.py | 755 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 295 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 10640 bytes .../__pycache__/_native.cpython-310.pyc | Bin 0 -> 2010 bytes .../site-packages/markupsafe/_native.py | 63 + .../site-packages/markupsafe/_speedups.c | 320 + .../_speedups.cpython-310-darwin.so | Bin 0 -> 117457 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../site-packages/markupsafe/py.typed | 0 .../pip-22.2.1.dist-info/INSTALLER | 1 + .../pip-22.2.1.dist-info/LICENSE.txt | 20 + .../pip-22.2.1.dist-info/METADATA | 90 + .../site-packages/pip-22.2.1.dist-info/RECORD | 992 ++ .../pip-22.2.1.dist-info/REQUESTED | 0 .../site-packages/pip-22.2.1.dist-info/WHEEL | 5 + .../pip-22.2.1.dist-info/entry_points.txt | 4 + .../pip-22.2.1.dist-info/top_level.txt | 1 + lib/python3.10/site-packages/pip/__init__.py | 13 + lib/python3.10/site-packages/pip/__main__.py | 31 + .../site-packages/pip/__pip-runner__.py | 37 + .../pip/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 635 bytes .../pip/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 597 bytes .../__pip-runner__.cpython-310.pyc | Bin 0 -> 1404 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 756 bytes .../__pycache__/build_env.cpython-310.pyc | Bin 0 -> 9187 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 9218 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 11216 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 23128 bytes .../__pycache__/main.cpython-310.pyc | Bin 0 -> 621 bytes .../__pycache__/pyproject.cpython-310.pyc | Bin 0 -> 3625 bytes .../self_outdated_check.cpython-310.pyc | Bin 0 -> 6577 bytes .../__pycache__/wheel_builder.cpython-310.pyc | Bin 0 -> 9209 bytes .../site-packages/pip/_internal/build_env.py | 290 + .../site-packages/pip/_internal/cache.py | 289 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 276 bytes .../autocompletion.cpython-310.pyc | Bin 0 -> 5311 bytes .../__pycache__/base_command.cpython-310.pyc | Bin 0 -> 6345 bytes .../__pycache__/cmdoptions.cpython-310.pyc | Bin 0 -> 23679 bytes .../command_context.cpython-310.pyc | Bin 0 -> 1316 bytes .../cli/__pycache__/main.cpython-310.pyc | Bin 0 -> 1374 bytes .../__pycache__/main_parser.cpython-310.pyc | Bin 0 -> 2160 bytes .../cli/__pycache__/parser.cpython-310.pyc | Bin 0 -> 9958 bytes .../__pycache__/progress_bars.cpython-310.pyc | Bin 0 -> 1900 bytes .../__pycache__/req_command.cpython-310.pyc | Bin 0 -> 13095 bytes .../cli/__pycache__/spinners.cpython-310.pyc | Bin 0 -> 4938 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 355 bytes .../pip/_internal/cli/autocompletion.py | 171 + .../pip/_internal/cli/base_command.py | 223 + .../pip/_internal/cli/cmdoptions.py | 1062 ++ .../pip/_internal/cli/command_context.py | 27 + .../site-packages/pip/_internal/cli/main.py | 70 + .../pip/_internal/cli/main_parser.py | 87 + .../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-310.pyc | Bin 0 -> 3255 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 6238 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 1573 bytes .../__pycache__/completion.cpython-310.pyc | Bin 0 -> 4164 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 8829 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 6670 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 4050 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 2638 bytes .../commands/__pycache__/hash.cpython-310.pyc | Bin 0 -> 2152 bytes .../commands/__pycache__/help.cpython-310.pyc | Bin 0 -> 1313 bytes .../__pycache__/index.cpython-310.pyc | Bin 0 -> 4562 bytes .../__pycache__/inspect.cpython-310.pyc | Bin 0 -> 3126 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 19423 bytes .../commands/__pycache__/list.cpython-310.pyc | Bin 0 -> 10194 bytes .../__pycache__/search.cpython-310.pyc | Bin 0 -> 5366 bytes .../commands/__pycache__/show.cpython-310.pyc | Bin 0 -> 6398 bytes .../__pycache__/uninstall.cpython-310.pyc | Bin 0 -> 3226 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4889 bytes .../pip/_internal/commands/cache.py | 223 + .../pip/_internal/commands/check.py | 53 + .../pip/_internal/commands/completion.py | 126 + .../pip/_internal/commands/configuration.py | 276 + .../pip/_internal/commands/debug.py | 199 + .../pip/_internal/commands/download.py | 142 + .../pip/_internal/commands/freeze.py | 97 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 138 + .../pip/_internal/commands/inspect.py | 97 + .../pip/_internal/commands/install.py | 827 ++ .../pip/_internal/commands/list.py | 360 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 183 + .../pip/_internal/commands/uninstall.py | 106 + .../pip/_internal/commands/wheel.py | 178 + .../pip/_internal/configuration.py | 374 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 803 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1891 bytes .../__pycache__/installed.cpython-310.pyc | Bin 0 -> 1268 bytes .../__pycache__/sdist.cpython-310.pyc | Bin 0 -> 4999 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1635 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 | 658 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 230 bytes .../__pycache__/collector.cpython-310.pyc | Bin 0 -> 17708 bytes .../package_finder.cpython-310.pyc | Bin 0 -> 29067 bytes .../index/__pycache__/sources.cpython-310.pyc | Bin 0 -> 7123 bytes .../pip/_internal/index/collector.py | 620 ++ .../pip/_internal/index/package_finder.py | 1025 ++ .../pip/_internal/index/sources.py | 224 + .../pip/_internal/locations/__init__.py | 530 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 12534 bytes .../__pycache__/_distutils.cpython-310.pyc | Bin 0 -> 4759 bytes .../__pycache__/_sysconfig.cpython-310.pyc | Bin 0 -> 6203 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 2406 bytes .../pip/_internal/locations/_distutils.py | 180 + .../pip/_internal/locations/_sysconfig.py | 218 + .../pip/_internal/locations/base.py | 81 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 105 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4011 bytes .../__pycache__/_json.cpython-310.pyc | Bin 0 -> 2190 bytes .../metadata/__pycache__/base.cpython-310.pyc | Bin 0 -> 25951 bytes .../__pycache__/pkg_resources.cpython-310.pyc | Bin 0 -> 9813 bytes .../pip/_internal/metadata/_json.py | 84 + .../pip/_internal/metadata/base.py | 670 ++ .../_internal/metadata/importlib/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 321 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 2127 bytes .../__pycache__/_dists.cpython-310.pyc | Bin 0 -> 8383 bytes .../__pycache__/_envs.cpython-310.pyc | Bin 0 -> 7494 bytes .../_internal/metadata/importlib/_compat.py | 43 + .../_internal/metadata/importlib/_dists.py | 206 + .../pip/_internal/metadata/importlib/_envs.py | 180 + .../pip/_internal/metadata/pkg_resources.py | 253 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 264 bytes .../__pycache__/candidate.cpython-310.pyc | Bin 0 -> 1416 bytes .../__pycache__/direct_url.cpython-310.pyc | Bin 0 -> 7110 bytes .../format_control.cpython-310.pyc | Bin 0 -> 2741 bytes .../models/__pycache__/index.cpython-310.pyc | Bin 0 -> 1233 bytes .../installation_report.cpython-310.pyc | Bin 0 -> 1743 bytes .../models/__pycache__/link.cpython-310.pyc | Bin 0 -> 10539 bytes .../models/__pycache__/scheme.cpython-310.pyc | Bin 0 -> 1032 bytes .../__pycache__/search_scope.cpython-310.pyc | Bin 0 -> 3487 bytes .../selection_prefs.cpython-310.pyc | Bin 0 -> 1694 bytes .../__pycache__/target_python.cpython-310.pyc | Bin 0 -> 3449 bytes .../models/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4443 bytes .../pip/_internal/models/candidate.py | 34 + .../pip/_internal/models/direct_url.py | 212 + .../pip/_internal/models/format_control.py | 80 + .../pip/_internal/models/index.py | 28 + .../_internal/models/installation_report.py | 53 + .../pip/_internal/models/link.py | 314 + .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 129 + .../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-310.pyc | Bin 0 -> 252 bytes .../network/__pycache__/auth.cpython-310.pyc | Bin 0 -> 7532 bytes .../network/__pycache__/cache.cpython-310.pyc | Bin 0 -> 2939 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 5534 bytes .../__pycache__/lazy_wheel.cpython-310.pyc | Bin 0 -> 8419 bytes .../__pycache__/session.cpython-310.pyc | Bin 0 -> 12432 bytes .../network/__pycache__/utils.cpython-310.pyc | Bin 0 -> 1455 bytes .../__pycache__/xmlrpc.cpython-310.pyc | Bin 0 -> 2065 bytes .../pip/_internal/network/auth.py | 323 + .../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-310.pyc | Bin 0 -> 200 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 4013 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 6205 bytes .../__pycache__/prepare.cpython-310.pyc | Bin 0 -> 14057 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 206 bytes .../__pycache__/build_tracker.cpython-310.pyc | Bin 0 -> 4287 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 1433 bytes .../metadata_editable.cpython-310.pyc | Bin 0 -> 1467 bytes .../metadata_legacy.cpython-310.pyc | Bin 0 -> 2378 bytes .../build/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1223 bytes .../wheel_editable.cpython-310.pyc | Bin 0 -> 1447 bytes .../__pycache__/wheel_legacy.cpython-310.pyc | Bin 0 -> 2763 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-310.pyc | Bin 0 -> 264 bytes .../editable_legacy.cpython-310.pyc | Bin 0 -> 1551 bytes .../__pycache__/legacy.cpython-310.pyc | Bin 0 -> 3349 bytes .../install/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 21123 bytes .../operations/install/editable_legacy.py | 47 + .../_internal/operations/install/legacy.py | 120 + .../pip/_internal/operations/install/wheel.py | 736 ++ .../pip/_internal/operations/prepare.py | 614 ++ .../site-packages/pip/_internal/pyproject.py | 175 + .../pip/_internal/req/__init__.py | 94 + .../req/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2607 bytes .../__pycache__/constructors.cpython-310.pyc | Bin 0 -> 12379 bytes .../req/__pycache__/req_file.cpython-310.pyc | Bin 0 -> 13544 bytes .../__pycache__/req_install.cpython-310.pyc | Bin 0 -> 22685 bytes .../req/__pycache__/req_set.cpython-310.pyc | Bin 0 -> 3915 bytes .../__pycache__/req_uninstall.cpython-310.pyc | Bin 0 -> 19066 bytes .../pip/_internal/req/constructors.py | 501 + .../pip/_internal/req/req_file.py | 540 ++ .../pip/_internal/req/req_install.py | 879 ++ .../pip/_internal/req/req_set.py | 82 + .../pip/_internal/req/req_uninstall.py | 640 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 200 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1052 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 207 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 14955 bytes .../_internal/resolution/legacy/resolver.py | 600 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 211 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 6454 bytes .../__pycache__/candidates.cpython-310.pyc | Bin 0 -> 18595 bytes .../__pycache__/factory.cpython-310.pyc | Bin 0 -> 19075 bytes .../found_candidates.cpython-310.pyc | Bin 0 -> 4871 bytes .../__pycache__/provider.cpython-310.pyc | Bin 0 -> 7712 bytes .../__pycache__/reporter.cpython-310.pyc | Bin 0 -> 3180 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 7469 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 8184 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 | 239 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 195 bytes .../utils/__pycache__/_log.cpython-310.pyc | Bin 0 -> 1523 bytes .../utils/__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 1621 bytes .../utils/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1511 bytes .../compatibility_tags.cpython-310.pyc | Bin 0 -> 4080 bytes .../__pycache__/datetime.cpython-310.pyc | Bin 0 -> 518 bytes .../__pycache__/deprecation.cpython-310.pyc | Bin 0 -> 3340 bytes .../direct_url_helpers.cpython-310.pyc | Bin 0 -> 2086 bytes .../distutils_args.cpython-310.pyc | Bin 0 -> 1060 bytes .../__pycache__/egg_link.cpython-310.pyc | Bin 0 -> 2151 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1308 bytes .../__pycache__/entrypoints.cpython-310.pyc | Bin 0 -> 2646 bytes .../__pycache__/filesystem.cpython-310.pyc | Bin 0 -> 4484 bytes .../__pycache__/filetypes.cpython-310.pyc | Bin 0 -> 945 bytes .../utils/__pycache__/glibc.cpython-310.pyc | Bin 0 -> 1674 bytes .../utils/__pycache__/hashes.cpython-310.pyc | Bin 0 -> 5197 bytes .../inject_securetransport.cpython-310.pyc | Bin 0 -> 990 bytes .../utils/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9722 bytes .../utils/__pycache__/misc.cpython-310.pyc | Bin 0 -> 21601 bytes .../utils/__pycache__/models.cpython-310.pyc | Bin 0 -> 1991 bytes .../__pycache__/packaging.cpython-310.pyc | Bin 0 -> 2083 bytes .../setuptools_build.cpython-310.pyc | Bin 0 -> 4598 bytes .../__pycache__/subprocess.cpython-310.pyc | Bin 0 -> 5771 bytes .../__pycache__/temp_dir.cpython-310.pyc | Bin 0 -> 7318 bytes .../__pycache__/unpacking.cpython-310.pyc | Bin 0 -> 6669 bytes .../utils/__pycache__/urls.cpython-310.pyc | Bin 0 -> 1596 bytes .../__pycache__/virtualenv.cpython-310.pyc | Bin 0 -> 3291 bytes .../utils/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4416 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 | 120 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/distutils_args.py | 43 + .../pip/_internal/utils/egg_link.py | 75 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 79 + .../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 | 723 ++ .../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-310.pyc | Bin 0 -> 518 bytes .../vcs/__pycache__/bazaar.cpython-310.pyc | Bin 0 -> 3345 bytes .../vcs/__pycache__/git.cpython-310.pyc | Bin 0 -> 12548 bytes .../vcs/__pycache__/mercurial.cpython-310.pyc | Bin 0 -> 5064 bytes .../__pycache__/subversion.cpython-310.pyc | Bin 0 -> 8452 bytes .../versioncontrol.cpython-310.pyc | Bin 0 -> 21147 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 101 + .../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 | 383 + .../site-packages/pip/_vendor/__init__.py | 120 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3131 bytes .../_vendor/__pycache__/six.cpython-310.pyc | Bin 0 -> 27589 bytes .../typing_extensions.cpython-310.pyc | Bin 0 -> 60729 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 646 bytes .../__pycache__/_cmd.cpython-310.pyc | Bin 0 -> 1584 bytes .../__pycache__/adapter.cpython-310.pyc | Bin 0 -> 3160 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 2694 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 760 bytes .../__pycache__/controller.cpython-310.pyc | Bin 0 -> 8600 bytes .../__pycache__/filewrapper.cpython-310.pyc | Bin 0 -> 2796 bytes .../__pycache__/heuristics.cpython-310.pyc | Bin 0 -> 4720 bytes .../__pycache__/serialize.cpython-310.pyc | Bin 0 -> 4335 bytes .../__pycache__/wrapper.cpython-310.pyc | Bin 0 -> 691 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-310.pyc | Bin 0 -> 365 bytes .../__pycache__/file_cache.cpython-310.pyc | Bin 0 -> 4965 bytes .../__pycache__/redis_cache.cpython-310.pyc | Bin 0 -> 1623 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-310.pyc | Bin 0 -> 308 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 458 bytes .../certifi/__pycache__/core.cpython-310.pyc | Bin 0 -> 1802 bytes .../pip/_vendor/certifi/cacert.pem | 4685 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 84 + .../pip/_vendor/chardet/__init__.py | 93 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2385 bytes .../__pycache__/big5freq.cpython-310.pyc | Bin 0 -> 27182 bytes .../__pycache__/big5prober.cpython-310.pyc | Bin 0 -> 1124 bytes .../chardistribution.cpython-310.pyc | Bin 0 -> 6227 bytes .../charsetgroupprober.cpython-310.pyc | Bin 0 -> 2218 bytes .../__pycache__/charsetprober.cpython-310.pyc | Bin 0 -> 3406 bytes .../codingstatemachine.cpython-310.pyc | Bin 0 -> 2891 bytes .../__pycache__/cp949prober.cpython-310.pyc | Bin 0 -> 1131 bytes .../chardet/__pycache__/enums.cpython-310.pyc | Bin 0 -> 2567 bytes .../__pycache__/escprober.cpython-310.pyc | Bin 0 -> 2612 bytes .../chardet/__pycache__/escsm.cpython-310.pyc | Bin 0 -> 8381 bytes .../__pycache__/eucjpprober.cpython-310.pyc | Bin 0 -> 2415 bytes .../__pycache__/euckrfreq.cpython-310.pyc | Bin 0 -> 12066 bytes .../__pycache__/euckrprober.cpython-310.pyc | Bin 0 -> 1132 bytes .../__pycache__/euctwfreq.cpython-310.pyc | Bin 0 -> 27186 bytes .../__pycache__/euctwprober.cpython-310.pyc | Bin 0 -> 1132 bytes .../__pycache__/gb2312freq.cpython-310.pyc | Bin 0 -> 19110 bytes .../__pycache__/gb2312prober.cpython-310.pyc | Bin 0 -> 1140 bytes .../__pycache__/hebrewprober.cpython-310.pyc | Bin 0 -> 3023 bytes .../__pycache__/jisfreq.cpython-310.pyc | Bin 0 -> 22138 bytes .../__pycache__/johabfreq.cpython-310.pyc | Bin 0 -> 138762 bytes .../__pycache__/johabprober.cpython-310.pyc | Bin 0 -> 1131 bytes .../__pycache__/jpcntx.cpython-310.pyc | Bin 0 -> 37634 bytes .../langbulgarianmodel.cpython-310.pyc | Bin 0 -> 47930 bytes .../langgreekmodel.cpython-310.pyc | Bin 0 -> 46120 bytes .../langhebrewmodel.cpython-310.pyc | Bin 0 -> 44567 bytes .../langhungarianmodel.cpython-310.pyc | Bin 0 -> 47890 bytes .../langrussianmodel.cpython-310.pyc | Bin 0 -> 61031 bytes .../__pycache__/langthaimodel.cpython-310.pyc | Bin 0 -> 44743 bytes .../langturkishmodel.cpython-310.pyc | Bin 0 -> 44584 bytes .../__pycache__/latin1prober.cpython-310.pyc | Bin 0 -> 4408 bytes .../mbcharsetprober.cpython-310.pyc | Bin 0 -> 2234 bytes .../mbcsgroupprober.cpython-310.pyc | Bin 0 -> 1185 bytes .../__pycache__/mbcssm.cpython-310.pyc | Bin 0 -> 20708 bytes .../sbcharsetprober.cpython-310.pyc | Bin 0 -> 3201 bytes .../sbcsgroupprober.cpython-310.pyc | Bin 0 -> 1724 bytes .../__pycache__/sjisprober.cpython-310.pyc | Bin 0 -> 2453 bytes .../universaldetector.cpython-310.pyc | Bin 0 -> 6470 bytes .../__pycache__/utf1632prober.cpython-310.pyc | Bin 0 -> 5884 bytes .../__pycache__/utf8prober.cpython-310.pyc | Bin 0 -> 1967 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 442 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 259 + .../pip/_vendor/chardet/charsetgroupprober.py | 109 + .../pip/_vendor/chardet/charsetprober.py | 138 + .../pip/_vendor/chardet/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 199 bytes .../__pycache__/chardetect.cpython-310.pyc | Bin 0 -> 2407 bytes .../pip/_vendor/chardet/cli/chardetect.py | 86 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 82 + .../pip/_vendor/chardet/escprober.py | 102 + .../pip/_vendor/chardet/escsm.py | 260 + .../pip/_vendor/chardet/eucjpprober.py | 95 + .../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 | 302 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/johabfreq.py | 2382 +++++ .../pip/_vendor/chardet/johabprober.py | 47 + .../pip/_vendor/chardet/jpcntx.py | 237 + .../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 | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 95 + .../pip/_vendor/chardet/mbcsgroupprober.py | 56 + .../pip/_vendor/chardet/mbcssm.py | 660 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 204 bytes .../__pycache__/languages.cpython-310.pyc | Bin 0 -> 7962 bytes .../pip/_vendor/chardet/metadata/languages.py | 351 + .../pip/_vendor/chardet/sbcharsetprober.py | 160 + .../pip/_vendor/chardet/sbcsgroupprober.py | 88 + .../pip/_vendor/chardet/sjisprober.py | 98 + .../pip/_vendor/chardet/universaldetector.py | 328 + .../pip/_vendor/chardet/utf1632prober.py | 223 + .../pip/_vendor/chardet/utf8prober.py | 80 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 447 bytes .../colorama/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 3008 bytes .../__pycache__/ansitowin32.cpython-310.pyc | Bin 0 -> 8210 bytes .../__pycache__/initialise.cpython-310.pyc | Bin 0 -> 1694 bytes .../__pycache__/win32.cpython-310.pyc | Bin 0 -> 3954 bytes .../__pycache__/winterm.cpython-310.pyc | Bin 0 -> 4571 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 266 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1066 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 31412 bytes .../__pycache__/database.cpython-310.pyc | Bin 0 -> 43152 bytes .../distlib/__pycache__/index.cpython-310.pyc | Bin 0 -> 17317 bytes .../__pycache__/locators.cpython-310.pyc | Bin 0 -> 38374 bytes .../__pycache__/manifest.cpython-310.pyc | Bin 0 -> 10234 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 5040 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 26791 bytes .../__pycache__/resources.cpython-310.pyc | Bin 0 -> 11040 bytes .../__pycache__/scripts.cpython-310.pyc | Bin 0 -> 11506 bytes .../distlib/__pycache__/util.cpython-310.pyc | Bin 0 -> 51701 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 20155 bytes .../distlib/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 28135 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/t32.exe | Bin 0 -> 97792 bytes .../pip/_vendor/distlib/t64-arm.exe | Bin 0 -> 182784 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 107520 bytes .../site-packages/pip/_vendor/distlib/util.py | 1932 ++++ .../pip/_vendor/distlib/version.py | 739 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 91648 bytes .../pip/_vendor/distlib/w64-arm.exe | Bin 0 -> 168448 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 101888 bytes .../pip/_vendor/distlib/wheel.py | 1082 +++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 919 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 273 bytes .../distro/__pycache__/distro.cpython-310.pyc | Bin 0 -> 41336 bytes .../pip/_vendor/distro/distro.py | 1374 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 851 bytes .../idna/__pycache__/codec.cpython-310.pyc | Bin 0 -> 2822 bytes .../idna/__pycache__/compat.cpython-310.pyc | Bin 0 -> 751 bytes .../idna/__pycache__/core.cpython-310.pyc | Bin 0 -> 9594 bytes .../idna/__pycache__/idnadata.cpython-310.pyc | Bin 0 -> 38229 bytes .../__pycache__/intranges.cpython-310.pyc | Bin 0 -> 1988 bytes .../__pycache__/package_data.cpython-310.pyc | Bin 0 -> 215 bytes .../__pycache__/uts46data.cpython-310.pyc | Bin 0 -> 150950 bytes .../site-packages/pip/_vendor/idna/codec.py | 112 + .../site-packages/pip/_vendor/idna/compat.py | 13 + .../site-packages/pip/_vendor/idna/core.py | 397 + .../pip/_vendor/idna/idnadata.py | 2137 +++++ .../pip/_vendor/idna/intranges.py | 54 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8512 +++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 57 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1449 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 1812 bytes .../msgpack/__pycache__/ext.cpython-310.pyc | Bin 0 -> 6320 bytes .../__pycache__/fallback.cpython-310.pyc | Bin 0 -> 25487 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-310.pyc | Bin 0 -> 594 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 450 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7304 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4616 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2709 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9293 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3979 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21531 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12200 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3579 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12929 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/pep517/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 317 bytes .../pep517/__pycache__/build.cpython-310.pyc | Bin 0 -> 3600 bytes .../pep517/__pycache__/check.cpython-310.pyc | Bin 0 -> 4564 bytes .../__pycache__/colorlog.cpython-310.pyc | Bin 0 -> 2968 bytes .../pep517/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1541 bytes .../__pycache__/dirtools.cpython-310.pyc | Bin 0 -> 1359 bytes .../__pycache__/envbuild.cpython-310.pyc | Bin 0 -> 4382 bytes .../pep517/__pycache__/meta.cpython-310.pyc | Bin 0 -> 2964 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 12310 bytes .../site-packages/pip/_vendor/pep517/build.py | 127 + .../site-packages/pip/_vendor/pep517/check.py | 207 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 51 + .../pip/_vendor/pep517/dirtools.py | 44 + .../pip/_vendor/pep517/envbuild.py | 171 + .../pip/_vendor/pep517/in_process/__init__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 925 bytes .../__pycache__/_in_process.cpython-310.pyc | Bin 0 -> 10072 bytes .../_vendor/pep517/in_process/_in_process.py | 363 + .../site-packages/pip/_vendor/pep517/meta.py | 92 + .../pip/_vendor/pep517/wrappers.py | 375 + .../pip/_vendor/pkg_resources/__init__.py | 3296 +++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 99894 bytes .../__pycache__/py31compat.cpython-310.pyc | Bin 0 -> 664 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/platformdirs/__init__.py | 340 + .../pip/_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 10532 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 1240 bytes .../__pycache__/android.cpython-310.pyc | Bin 0 -> 4330 bytes .../__pycache__/api.cpython-310.pyc | Bin 0 -> 5206 bytes .../__pycache__/macos.cpython-310.pyc | Bin 0 -> 3194 bytes .../__pycache__/unix.cpython-310.pyc | Bin 0 -> 6895 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 297 bytes .../__pycache__/windows.cpython-310.pyc | Bin 0 -> 6438 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 | 182 + .../pip/_vendor/pygments/__init__.py | 83 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3004 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 592 bytes .../__pycache__/cmdline.cpython-310.pyc | Bin 0 -> 15457 bytes .../__pycache__/console.cpython-310.pyc | Bin 0 -> 1887 bytes .../__pycache__/filter.cpython-310.pyc | Bin 0 -> 2658 bytes .../__pycache__/formatter.cpython-310.pyc | Bin 0 -> 3014 bytes .../__pycache__/lexer.cpython-310.pyc | Bin 0 -> 24377 bytes .../__pycache__/modeline.cpython-310.pyc | Bin 0 -> 1196 bytes .../__pycache__/plugin.cpython-310.pyc | Bin 0 -> 2048 bytes .../__pycache__/regexopt.cpython-310.pyc | Bin 0 -> 2960 bytes .../__pycache__/scanner.cpython-310.pyc | Bin 0 -> 3562 bytes .../__pycache__/sphinxext.cpython-310.pyc | Bin 0 -> 4546 bytes .../__pycache__/style.cpython-310.pyc | Bin 0 -> 4583 bytes .../__pycache__/token.cpython-310.pyc | Bin 0 -> 4655 bytes .../__pycache__/unistring.cpython-310.pyc | Bin 0 -> 31209 bytes .../pygments/__pycache__/util.cpython-310.pyc | Bin 0 -> 9151 bytes .../pip/_vendor/pygments/cmdline.py | 663 ++ .../pip/_vendor/pygments/console.py | 70 + .../pip/_vendor/pygments/filter.py | 71 + .../pip/_vendor/pygments/filters/__init__.py | 937 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 29521 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 153 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4672 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 5540 bytes .../__pycache__/bbcode.cpython-310.pyc | Bin 0 -> 3089 bytes .../__pycache__/groff.cpython-310.pyc | Bin 0 -> 4402 bytes .../__pycache__/html.cpython-310.pyc | Bin 0 -> 29136 bytes .../__pycache__/img.cpython-310.pyc | Bin 0 -> 17501 bytes .../__pycache__/irc.cpython-310.pyc | Bin 0 -> 4592 bytes .../__pycache__/latex.cpython-310.pyc | Bin 0 -> 13802 bytes .../__pycache__/other.cpython-310.pyc | Bin 0 -> 4808 bytes .../__pycache__/pangomarkup.cpython-310.pyc | Bin 0 -> 2108 bytes .../__pycache__/rtf.cpython-310.pyc | Bin 0 -> 4138 bytes .../__pycache__/svg.cpython-310.pyc | Bin 0 -> 6336 bytes .../__pycache__/terminal.cpython-310.pyc | Bin 0 -> 4003 bytes .../__pycache__/terminal256.cpython-310.pyc | Bin 0 -> 9253 bytes .../_vendor/pygments/formatters/_mapping.py | 84 + .../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 | 641 ++ .../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 | 345 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9358 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 60153 bytes .../lexers/__pycache__/python.cpython-310.pyc | Bin 0 -> 29361 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 596 ++ .../pip/_vendor/pygments/lexers/python.py | 1191 +++ .../pip/_vendor/pygments/modeline.py | 43 + .../pip/_vendor/pygments/plugin.py | 69 + .../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 | 93 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3224 bytes .../pip/_vendor/pygments/token.py | 212 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 308 + .../pip/_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7133 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7183 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10109 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 176524 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9067 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 35344 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24791 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12103 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 10062 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8609 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-310.pyc | Bin 0 -> 16597 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/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4020 bytes .../__pycache__/__version__.cpython-310.pyc | Bin 0 -> 559 bytes .../_internal_utils.cpython-310.pyc | Bin 0 -> 1569 bytes .../__pycache__/adapters.cpython-310.pyc | Bin 0 -> 16903 bytes .../requests/__pycache__/api.cpython-310.pyc | Bin 0 -> 6658 bytes .../requests/__pycache__/auth.cpython-310.pyc | Bin 0 -> 8126 bytes .../__pycache__/certs.cpython-310.pyc | Bin 0 -> 643 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 1375 bytes .../__pycache__/cookies.cpython-310.pyc | Bin 0 -> 18701 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5745 bytes .../requests/__pycache__/help.cpython-310.pyc | Bin 0 -> 2871 bytes .../__pycache__/hooks.cpython-310.pyc | Bin 0 -> 998 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 24271 bytes .../__pycache__/packages.cpython-310.pyc | Bin 0 -> 512 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 19590 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 4677 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 4442 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 24340 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 | 17 + .../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-310.pyc | Bin 0 -> 610 bytes .../__pycache__/providers.cpython-310.pyc | Bin 0 -> 6661 bytes .../__pycache__/reporters.cpython-310.pyc | Bin 0 -> 2581 bytes .../__pycache__/resolvers.cpython-310.pyc | Bin 0 -> 15134 bytes .../__pycache__/structs.cpython-310.pyc | Bin 0 -> 7167 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 205 bytes .../collections_abc.cpython-310.pyc | Bin 0 -> 381 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 | 176 + .../pip/_vendor/rich/__main__.py | 282 + .../rich/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5978 bytes .../rich/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 7300 bytes .../__pycache__/_cell_widths.cpython-310.pyc | Bin 0 -> 7818 bytes .../__pycache__/_emoji_codes.cpython-310.pyc | Bin 0 -> 360058 bytes .../_emoji_replace.cpython-310.pyc | Bin 0 -> 1198 bytes .../_export_format.cpython-310.pyc | Bin 0 -> 2315 bytes .../__pycache__/_extension.cpython-310.pyc | Bin 0 -> 499 bytes .../rich/__pycache__/_inspect.cpython-310.pyc | Bin 0 -> 8676 bytes .../__pycache__/_log_render.cpython-310.pyc | Bin 0 -> 2644 bytes .../rich/__pycache__/_loop.cpython-310.pyc | Bin 0 -> 1296 bytes .../__pycache__/_palettes.cpython-310.pyc | Bin 0 -> 5101 bytes .../rich/__pycache__/_pick.cpython-310.pyc | Bin 0 -> 644 bytes .../rich/__pycache__/_ratio.cpython-310.pyc | Bin 0 -> 5163 bytes .../__pycache__/_spinners.cpython-310.pyc | Bin 0 -> 12275 bytes .../rich/__pycache__/_stack.cpython-310.pyc | Bin 0 -> 842 bytes .../rich/__pycache__/_timer.cpython-310.pyc | Bin 0 -> 691 bytes .../_win32_console.cpython-310.pyc | Bin 0 -> 19011 bytes .../rich/__pycache__/_windows.cpython-310.pyc | Bin 0 -> 1793 bytes .../_windows_renderer.cpython-310.pyc | Bin 0 -> 2047 bytes .../rich/__pycache__/_wrap.cpython-310.pyc | Bin 0 -> 1555 bytes .../rich/__pycache__/abc.cpython-310.pyc | Bin 0 -> 1318 bytes .../rich/__pycache__/align.cpython-310.pyc | Bin 0 -> 7953 bytes .../rich/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 5960 bytes .../rich/__pycache__/bar.cpython-310.pyc | Bin 0 -> 2987 bytes .../rich/__pycache__/box.cpython-310.pyc | Bin 0 -> 8407 bytes .../rich/__pycache__/cells.cpython-310.pyc | Bin 0 -> 3977 bytes .../rich/__pycache__/color.cpython-310.pyc | Bin 0 -> 17465 bytes .../__pycache__/color_triplet.cpython-310.pyc | Bin 0 -> 1441 bytes .../rich/__pycache__/columns.cpython-310.pyc | Bin 0 -> 6201 bytes .../rich/__pycache__/console.cpython-310.pyc | Bin 0 -> 80961 bytes .../__pycache__/constrain.cpython-310.pyc | Bin 0 -> 1758 bytes .../__pycache__/containers.cpython-310.pyc | Bin 0 -> 6490 bytes .../rich/__pycache__/control.cpython-310.pyc | Bin 0 -> 8163 bytes .../default_styles.cpython-310.pyc | Bin 0 -> 6202 bytes .../rich/__pycache__/diagnose.cpython-310.pyc | Bin 0 -> 1225 bytes .../rich/__pycache__/emoji.cpython-310.pyc | Bin 0 -> 3271 bytes .../rich/__pycache__/errors.cpython-310.pyc | Bin 0 -> 1531 bytes .../__pycache__/file_proxy.cpython-310.pyc | Bin 0 -> 2264 bytes .../rich/__pycache__/filesize.cpython-310.pyc | Bin 0 -> 2620 bytes .../__pycache__/highlighter.cpython-310.pyc | Bin 0 -> 8064 bytes .../rich/__pycache__/json.cpython-310.pyc | Bin 0 -> 4751 bytes .../rich/__pycache__/jupyter.cpython-310.pyc | Bin 0 -> 4003 bytes .../rich/__pycache__/layout.cpython-310.pyc | Bin 0 -> 14690 bytes .../rich/__pycache__/live.cpython-310.pyc | Bin 0 -> 11628 bytes .../__pycache__/live_render.cpython-310.pyc | Bin 0 -> 3406 bytes .../rich/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9777 bytes .../rich/__pycache__/markup.cpython-310.pyc | Bin 0 -> 5945 bytes .../rich/__pycache__/measure.cpython-310.pyc | Bin 0 -> 5080 bytes .../rich/__pycache__/padding.cpython-310.pyc | Bin 0 -> 4486 bytes .../rich/__pycache__/pager.cpython-310.pyc | Bin 0 -> 1480 bytes .../rich/__pycache__/palette.cpython-310.pyc | Bin 0 -> 3712 bytes .../rich/__pycache__/panel.cpython-310.pyc | Bin 0 -> 6423 bytes .../rich/__pycache__/pretty.cpython-310.pyc | Bin 0 -> 27407 bytes .../rich/__pycache__/progress.cpython-310.pyc | Bin 0 -> 53906 bytes .../__pycache__/progress_bar.cpython-310.pyc | Bin 0 -> 6911 bytes .../rich/__pycache__/prompt.cpython-310.pyc | Bin 0 -> 11305 bytes .../rich/__pycache__/protocol.cpython-310.pyc | Bin 0 -> 1356 bytes .../rich/__pycache__/region.cpython-310.pyc | Bin 0 -> 531 bytes .../rich/__pycache__/repr.cpython-310.pyc | Bin 0 -> 4119 bytes .../rich/__pycache__/rule.cpython-310.pyc | Bin 0 -> 4313 bytes .../rich/__pycache__/scope.cpython-310.pyc | Bin 0 -> 2992 bytes .../rich/__pycache__/screen.cpython-310.pyc | Bin 0 -> 1883 bytes .../rich/__pycache__/segment.cpython-310.pyc | Bin 0 -> 20761 bytes .../rich/__pycache__/spinner.cpython-310.pyc | Bin 0 -> 4421 bytes .../rich/__pycache__/status.cpython-310.pyc | Bin 0 -> 4597 bytes .../rich/__pycache__/style.cpython-310.pyc | Bin 0 -> 20793 bytes .../rich/__pycache__/styled.cpython-310.pyc | Bin 0 -> 1767 bytes .../rich/__pycache__/syntax.cpython-310.pyc | Bin 0 -> 25366 bytes .../rich/__pycache__/table.cpython-310.pyc | Bin 0 -> 29733 bytes .../terminal_theme.cpython-310.pyc | Bin 0 -> 3020 bytes .../rich/__pycache__/text.cpython-310.pyc | Bin 0 -> 39424 bytes .../rich/__pycache__/theme.cpython-310.pyc | Bin 0 -> 4704 bytes .../rich/__pycache__/themes.cpython-310.pyc | Bin 0 -> 297 bytes .../__pycache__/traceback.cpython-310.pyc | Bin 0 -> 19653 bytes .../rich/__pycache__/tree.cpython-310.pyc | Bin 0 -> 7338 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/_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 | 615 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2572 +++++ .../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 | 445 + .../site-packages/pip/_vendor/rich/live.py | 373 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 280 + .../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 | 251 + .../site-packages/pip/_vendor/rich/pretty.py | 1010 ++ .../pip/_vendor/rich/progress.py | 1703 ++++ .../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 | 152 + .../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 | 771 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 934 ++ .../site-packages/pip/_vendor/rich/table.py | 996 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1286 +++ .../site-packages/pip/_vendor/rich/theme.py | 112 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 679 ++ .../site-packages/pip/_vendor/rich/tree.py | 251 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 517 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16378 bytes .../__pycache__/_asyncio.cpython-310.pyc | Bin 0 -> 2618 bytes .../__pycache__/_utils.cpython-310.pyc | Bin 0 -> 1231 bytes .../__pycache__/after.cpython-310.pyc | Bin 0 -> 1235 bytes .../__pycache__/before.cpython-310.pyc | Bin 0 -> 1113 bytes .../__pycache__/before_sleep.cpython-310.pyc | Bin 0 -> 1415 bytes .../tenacity/__pycache__/nap.cpython-310.pyc | Bin 0 -> 1203 bytes .../__pycache__/retry.cpython-310.pyc | Bin 0 -> 8433 bytes .../tenacity/__pycache__/stop.cpython-310.pyc | Bin 0 -> 4021 bytes .../__pycache__/tornadoweb.cpython-310.pyc | Bin 0 -> 1768 bytes .../tenacity/__pycache__/wait.cpython-310.pyc | Bin 0 -> 7965 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 | 213 + .../pip/_vendor/tenacity/stop.py | 96 + .../pip/_vendor/tenacity/tornadoweb.py | 59 + .../pip/_vendor/tenacity/wait.py | 191 + .../pip/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 359 bytes .../tomli/__pycache__/_parser.cpython-310.pyc | Bin 0 -> 17073 bytes .../tomli/__pycache__/_re.cpython-310.pyc | Bin 0 -> 2905 bytes .../tomli/__pycache__/_types.cpython-310.pyc | Bin 0 -> 329 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 | 2069 ++++ .../pip/_vendor/urllib3/__init__.py | 85 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2193 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 10867 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 218 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 13647 bytes .../connectionpool.cpython-310.pyc | Bin 0 -> 25409 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10998 bytes .../__pycache__/fields.cpython-310.pyc | Bin 0 -> 8189 bytes .../__pycache__/filepost.cpython-310.pyc | Bin 0 -> 2754 bytes .../__pycache__/poolmanager.cpython-310.pyc | Bin 0 -> 15223 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 5630 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 20878 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-310.pyc | Bin 0 -> 203 bytes .../_appengine_environ.cpython-310.pyc | Bin 0 -> 1383 bytes .../__pycache__/appengine.cpython-310.pyc | Bin 0 -> 8199 bytes .../__pycache__/ntlmpool.cpython-310.pyc | Bin 0 -> 3638 bytes .../__pycache__/pyopenssl.cpython-310.pyc | Bin 0 -> 15542 bytes .../securetransport.cpython-310.pyc | Bin 0 -> 21945 bytes .../contrib/__pycache__/socks.cpython-310.pyc | Bin 0 -> 5605 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 220 bytes .../__pycache__/bindings.cpython-310.pyc | Bin 0 -> 10716 bytes .../__pycache__/low_level.cpython-310.pyc | Bin 0 -> 9103 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 | 510 + .../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-310.pyc | Bin 0 -> 204 bytes .../packages/__pycache__/six.cpython-310.pyc | Bin 0 -> 27664 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 214 bytes .../__pycache__/makefile.cpython-310.pyc | Bin 0 -> 1314 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 | 818 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1113 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 3441 bytes .../util/__pycache__/proxy.cpython-310.pyc | Bin 0 -> 1348 bytes .../util/__pycache__/queue.cpython-310.pyc | Bin 0 -> 1068 bytes .../util/__pycache__/request.cpython-310.pyc | Bin 0 -> 3375 bytes .../util/__pycache__/response.cpython-310.pyc | Bin 0 -> 2361 bytes .../util/__pycache__/retry.cpython-310.pyc | Bin 0 -> 16146 bytes .../util/__pycache__/ssl_.cpython-310.pyc | Bin 0 -> 11315 bytes .../ssl_match_hostname.cpython-310.pyc | Bin 0 -> 3265 bytes .../__pycache__/ssltransport.cpython-310.pyc | Bin 0 -> 7403 bytes .../util/__pycache__/timeout.cpython-310.pyc | Bin 0 -> 8945 bytes .../util/__pycache__/url.cpython-310.pyc | Bin 0 -> 10701 bytes .../util/__pycache__/wait.cpython-310.pyc | Bin 0 -> 3097 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-310.pyc | Bin 0 -> 9750 bytes .../__pycache__/labels.cpython-310.pyc | Bin 0 -> 5240 bytes .../__pycache__/mklabels.cpython-310.pyc | Bin 0 -> 1945 bytes .../__pycache__/tests.cpython-310.pyc | Bin 0 -> 5047 bytes .../x_user_defined.cpython-310.pyc | Bin 0 -> 2596 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.10/site-packages/pip/py.typed | 4 + .../site-packages/pkg_resources/__init__.py | 3296 +++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 100579 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 197 bytes .../__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 20258 bytes .../_vendor/__pycache__/zipp.cpython-310.pyc | Bin 0 -> 10240 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 652 bytes .../__pycache__/_adapters.cpython-310.pyc | Bin 0 -> 7360 bytes .../__pycache__/_common.cpython-310.pyc | Bin 0 -> 2650 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 3510 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 897 bytes .../__pycache__/_legacy.cpython-310.pyc | Bin 0 -> 4233 bytes .../__pycache__/abc.cpython-310.pyc | Bin 0 -> 5386 bytes .../__pycache__/readers.cpython-310.pyc | Bin 0 -> 5470 bytes .../__pycache__/simple.cpython-310.pyc | Bin 0 -> 4738 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-310.pyc | Bin 0 -> 204 bytes .../__pycache__/context.cpython-310.pyc | Bin 0 -> 6336 bytes .../__pycache__/functools.cpython-310.pyc | Bin 0 -> 15628 bytes .../pkg_resources/_vendor/jaraco/context.py | 213 + .../pkg_resources/_vendor/jaraco/functools.py | 525 + .../_vendor/jaraco/text/__init__.py | 599 ++ .../text/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 19673 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 279 bytes .../__pycache__/more.cpython-310.pyc | Bin 0 -> 123064 bytes .../__pycache__/recipes.cpython-310.pyc | Bin 0 -> 20340 bytes .../_vendor/more_itertools/more.py | 4316 +++++++++ .../_vendor/more_itertools/recipes.py | 698 ++ .../_vendor/packaging/__about__.py | 26 + .../_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 604 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 460 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7314 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4626 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2719 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9312 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3998 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21541 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12210 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3589 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12939 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/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7131 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7196 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10119 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 176408 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9086 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 35263 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24813 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12116 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 9828 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8619 bytes .../_vendor/pyparsing/actions.py | 207 + .../pkg_resources/_vendor/pyparsing/common.py | 424 + .../pkg_resources/_vendor/pyparsing/core.py | 5812 +++++++++++ .../_vendor/pyparsing/diagram/__init__.py | 611 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16077 bytes .../_vendor/pyparsing/exceptions.py | 267 + .../_vendor/pyparsing/helpers.py | 1083 +++ .../_vendor/pyparsing/results.py | 760 ++ .../_vendor/pyparsing/testing.py | 331 + .../_vendor/pyparsing/unicode.py | 332 + .../pkg_resources/_vendor/pyparsing/util.py | 235 + .../pkg_resources/_vendor/zipp.py | 329 + .../pkg_resources/extern/__init__.py | 76 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2950 bytes .../setuptools-63.2.0.dist-info/INSTALLER | 1 + .../setuptools-63.2.0.dist-info/LICENSE | 19 + .../setuptools-63.2.0.dist-info/METADATA | 140 + .../setuptools-63.2.0.dist-info/RECORD | 468 + .../setuptools-63.2.0.dist-info/REQUESTED | 0 .../setuptools-63.2.0.dist-info/WHEEL | 5 + .../entry_points.txt | 56 + .../setuptools-63.2.0.dist-info/top_level.txt | 3 + .../site-packages/setuptools/__init__.py | 189 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 6586 bytes .../_deprecation_warning.cpython-310.pyc | Bin 0 -> 558 bytes .../__pycache__/_entry_points.cpython-310.pyc | Bin 0 -> 3021 bytes .../__pycache__/_imp.cpython-310.pyc | Bin 0 -> 2084 bytes .../__pycache__/_importlib.cpython-310.pyc | Bin 0 -> 1354 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 922 bytes .../__pycache__/_path.cpython-310.pyc | Bin 0 -> 434 bytes .../__pycache__/_reqs.cpython-310.pyc | Bin 0 -> 837 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 6188 bytes .../__pycache__/build_meta.cpython-310.pyc | Bin 0 -> 9872 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 865 bytes .../__pycache__/depends.cpython-310.pyc | Bin 0 -> 5304 bytes .../__pycache__/discovery.cpython-310.pyc | Bin 0 -> 20583 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 38412 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 2492 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 5584 bytes .../__pycache__/glob.cpython-310.pyc | Bin 0 -> 3743 bytes .../__pycache__/installer.cpython-310.pyc | Bin 0 -> 2989 bytes .../__pycache__/launch.cpython-310.pyc | Bin 0 -> 915 bytes .../__pycache__/logging.cpython-310.pyc | Bin 0 -> 1218 bytes .../__pycache__/monkey.cpython-310.pyc | Bin 0 -> 4643 bytes .../__pycache__/msvc.cpython-310.pyc | Bin 0 -> 42647 bytes .../__pycache__/namespaces.cpython-310.pyc | Bin 0 -> 3626 bytes .../__pycache__/package_index.cpython-310.pyc | Bin 0 -> 32695 bytes .../__pycache__/py34compat.cpython-310.pyc | Bin 0 -> 490 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 15766 bytes .../__pycache__/unicode_utils.cpython-310.pyc | Bin 0 -> 1120 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 332 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 7382 bytes .../windows_support.cpython-310.pyc | Bin 0 -> 1038 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 24 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 566 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 2067 bytes .../__pycache__/_functools.cpython-310.pyc | Bin 0 -> 697 bytes .../__pycache__/_macos_compat.cpython-310.pyc | Bin 0 -> 461 bytes .../__pycache__/_msvccompiler.cpython-310.pyc | Bin 0 -> 13867 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 6577 bytes .../__pycache__/bcppcompiler.cpython-310.pyc | Bin 0 -> 6587 bytes .../__pycache__/ccompiler.cpython-310.pyc | Bin 0 -> 33372 bytes .../__pycache__/cmd.cpython-310.pyc | Bin 0 -> 13970 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 3592 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 7094 bytes .../cygwinccompiler.cpython-310.pyc | Bin 0 -> 8342 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 260 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 2777 bytes .../__pycache__/dir_util.cpython-310.pyc | Bin 0 -> 5926 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 34132 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 5002 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 7018 bytes .../__pycache__/fancy_getopt.cpython-310.pyc | Bin 0 -> 10648 bytes .../__pycache__/file_util.cpython-310.pyc | Bin 0 -> 5972 bytes .../__pycache__/filelist.cpython-310.pyc | Bin 0 -> 10808 bytes .../__pycache__/log.cpython-310.pyc | Bin 0 -> 2317 bytes .../__pycache__/msvc9compiler.cpython-310.pyc | Bin 0 -> 17539 bytes .../__pycache__/msvccompiler.cpython-310.pyc | Bin 0 -> 14799 bytes .../__pycache__/py38compat.cpython-310.pyc | Bin 0 -> 433 bytes .../__pycache__/py39compat.cpython-310.pyc | Bin 0 -> 742 bytes .../__pycache__/spawn.cpython-310.pyc | Bin 0 -> 2862 bytes .../__pycache__/sysconfig.cpython-310.pyc | Bin 0 -> 12586 bytes .../__pycache__/text_file.cpython-310.pyc | Bin 0 -> 8263 bytes .../__pycache__/unixccompiler.cpython-310.pyc | Bin 0 -> 8654 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 13514 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 7835 bytes .../versionpredicate.cpython-310.pyc | Bin 0 -> 5335 bytes .../setuptools/_distutils/_collections.py | 56 + .../setuptools/_distutils/_functools.py | 20 + .../setuptools/_distutils/_macos_compat.py | 12 + .../setuptools/_distutils/_msvccompiler.py | 591 ++ .../setuptools/_distutils/archive_util.py | 280 + .../setuptools/_distutils/bcppcompiler.py | 398 + .../setuptools/_distutils/ccompiler.py | 1193 +++ .../setuptools/_distutils/cmd.py | 434 + .../setuptools/_distutils/command/__init__.py | 32 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 539 bytes .../_framework_compat.cpython-310.pyc | Bin 0 -> 1931 bytes .../command/__pycache__/bdist.cpython-310.pyc | Bin 0 -> 3654 bytes .../__pycache__/bdist_dumb.cpython-310.pyc | Bin 0 -> 3648 bytes .../__pycache__/bdist_msi.cpython-310.pyc | Bin 0 -> 20203 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 12281 bytes .../__pycache__/bdist_wininst.cpython-310.pyc | Bin 0 -> 8621 bytes .../command/__pycache__/build.cpython-310.pyc | Bin 0 -> 3905 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 4870 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 16234 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 9807 bytes .../__pycache__/build_scripts.cpython-310.pyc | Bin 0 -> 4608 bytes .../command/__pycache__/check.cpython-310.pyc | Bin 0 -> 4561 bytes .../command/__pycache__/clean.cpython-310.pyc | Bin 0 -> 2140 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 10370 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 17226 bytes .../__pycache__/install_data.cpython-310.pyc | Bin 0 -> 2361 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 3320 bytes .../install_headers.cpython-310.pyc | Bin 0 -> 1776 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 5204 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2209 bytes .../__pycache__/py37compat.cpython-310.pyc | Bin 0 -> 1052 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 8576 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 14513 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 5363 bytes .../_distutils/command/_framework_compat.py | 55 + .../setuptools/_distutils/command/bdist.py | 155 + .../_distutils/command/bdist_dumb.py | 142 + .../_distutils/command/bdist_msi.py | 1114 +++ .../_distutils/command/bdist_rpm.py | 607 ++ .../_distutils/command/bdist_wininst.py | 418 + .../setuptools/_distutils/command/build.py | 152 + .../_distutils/command/build_clib.py | 208 + .../_distutils/command/build_ext.py | 780 ++ .../setuptools/_distutils/command/build_py.py | 408 + .../_distutils/command/build_scripts.py | 173 + .../setuptools/_distutils/command/check.py | 153 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 376 + .../setuptools/_distutils/command/install.py | 811 ++ .../_distutils/command/install_data.py | 84 + .../_distutils/command/install_egg_info.py | 87 + .../_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 | 319 + .../setuptools/_distutils/command/sdist.py | 531 + .../setuptools/_distutils/command/upload.py | 205 + .../setuptools/_distutils/config.py | 139 + .../setuptools/_distutils/core.py | 283 + .../setuptools/_distutils/cygwinccompiler.py | 414 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 96 + .../setuptools/_distutils/dir_util.py | 239 + .../setuptools/_distutils/dist.py | 1286 +++ .../setuptools/_distutils/errors.py | 127 + .../setuptools/_distutils/extension.py | 248 + .../setuptools/_distutils/fancy_getopt.py | 468 + .../setuptools/_distutils/file_util.py | 245 + .../setuptools/_distutils/filelist.py | 371 + .../setuptools/_distutils/log.py | 80 + .../setuptools/_distutils/msvc9compiler.py | 820 ++ .../setuptools/_distutils/msvccompiler.py | 683 ++ .../setuptools/_distutils/py38compat.py | 8 + .../setuptools/_distutils/py39compat.py | 22 + .../setuptools/_distutils/spawn.py | 107 + .../setuptools/_distutils/sysconfig.py | 549 ++ .../setuptools/_distutils/text_file.py | 287 + .../setuptools/_distutils/unixccompiler.py | 382 + .../setuptools/_distutils/util.py | 520 + .../setuptools/_distutils/version.py | 358 + .../setuptools/_distutils/versionpredicate.py | 175 + .../site-packages/setuptools/_entry_points.py | 86 + .../site-packages/setuptools/_imp.py | 82 + .../site-packages/setuptools/_importlib.py | 47 + .../site-packages/setuptools/_itertools.py | 23 + .../site-packages/setuptools/_path.py | 7 + .../site-packages/setuptools/_reqs.py | 19 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 194 bytes .../__pycache__/ordered_set.cpython-310.pyc | Bin 0 -> 16330 bytes .../typing_extensions.cpython-310.pyc | Bin 0 -> 66608 bytes .../_vendor/__pycache__/zipp.cpython-310.pyc | Bin 0 -> 10237 bytes .../_vendor/importlib_metadata/__init__.py | 1047 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 37429 bytes .../__pycache__/_adapters.cpython-310.pyc | Bin 0 -> 2414 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 1589 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 2078 bytes .../__pycache__/_functools.cpython-310.pyc | Bin 0 -> 3179 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 2060 bytes .../__pycache__/_meta.cpython-310.pyc | Bin 0 -> 2368 bytes .../__pycache__/_text.cpython-310.pyc | Bin 0 -> 3112 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-310.pyc | Bin 0 -> 649 bytes .../__pycache__/_adapters.cpython-310.pyc | Bin 0 -> 7357 bytes .../__pycache__/_common.cpython-310.pyc | Bin 0 -> 2647 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 3507 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 894 bytes .../__pycache__/_legacy.cpython-310.pyc | Bin 0 -> 4230 bytes .../__pycache__/abc.cpython-310.pyc | Bin 0 -> 5383 bytes .../__pycache__/readers.cpython-310.pyc | Bin 0 -> 5467 bytes .../__pycache__/simple.cpython-310.pyc | Bin 0 -> 4735 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-310.pyc | Bin 0 -> 201 bytes .../__pycache__/context.cpython-310.pyc | Bin 0 -> 6333 bytes .../__pycache__/functools.cpython-310.pyc | Bin 0 -> 15619 bytes .../setuptools/_vendor/jaraco/context.py | 213 + .../setuptools/_vendor/jaraco/functools.py | 525 + .../_vendor/jaraco/text/__init__.py | 599 ++ .../text/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 19661 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 275 bytes .../__pycache__/more.cpython-310.pyc | Bin 0 -> 110008 bytes .../__pycache__/recipes.cpython-310.pyc | Bin 0 -> 17975 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-310.pyc | Bin 0 -> 601 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 457 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7311 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4623 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2716 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9306 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3992 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21538 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12207 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3586 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12936 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-310.pyc | Bin 0 -> 7128 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7193 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10116 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 176405 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9083 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 35260 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24810 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12113 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 9825 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8616 bytes .../setuptools/_vendor/pyparsing/actions.py | 207 + .../setuptools/_vendor/pyparsing/common.py | 424 + .../setuptools/_vendor/pyparsing/core.py | 5812 +++++++++++ .../_vendor/pyparsing/diagram/__init__.py | 611 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16074 bytes .../_vendor/pyparsing/exceptions.py | 267 + .../setuptools/_vendor/pyparsing/helpers.py | 1083 +++ .../setuptools/_vendor/pyparsing/results.py | 760 ++ .../setuptools/_vendor/pyparsing/testing.py | 331 + .../setuptools/_vendor/pyparsing/unicode.py | 332 + .../setuptools/_vendor/pyparsing/util.py | 235 + .../setuptools/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 366 bytes .../tomli/__pycache__/_parser.cpython-310.pyc | Bin 0 -> 17080 bytes .../tomli/__pycache__/_re.cpython-310.pyc | Bin 0 -> 2912 bytes .../tomli/__pycache__/_types.cpython-310.pyc | Bin 0 -> 336 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 | 304 + .../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 | 8 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 383 bytes .../command/__pycache__/alias.cpython-310.pyc | Bin 0 -> 2385 bytes .../__pycache__/bdist_egg.cpython-310.pyc | Bin 0 -> 13135 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 1598 bytes .../command/__pycache__/build.cpython-310.pyc | Bin 0 -> 1228 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 2474 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 9901 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 10680 bytes .../__pycache__/develop.cpython-310.pyc | Bin 0 -> 6161 bytes .../__pycache__/dist_info.cpython-310.pyc | Bin 0 -> 2642 bytes .../__pycache__/easy_install.cpython-310.pyc | Bin 0 -> 64434 bytes .../__pycache__/egg_info.cpython-310.pyc | Bin 0 -> 22903 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 4294 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 2468 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 4180 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2462 bytes .../__pycache__/py36compat.cpython-310.pyc | Bin 0 -> 4545 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 849 bytes .../__pycache__/rotate.cpython-310.pyc | Bin 0 -> 2516 bytes .../__pycache__/saveopts.cpython-310.pyc | Bin 0 -> 935 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 6993 bytes .../__pycache__/setopt.cpython-310.pyc | Bin 0 -> 4697 bytes .../command/__pycache__/test.cpython-310.pyc | Bin 0 -> 8239 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 822 bytes .../__pycache__/upload_docs.cpython-310.pyc | Bin 0 -> 6412 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 | 24 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_py.py | 298 + .../setuptools/command/develop.py | 193 + .../setuptools/command/dist_info.py | 69 + .../setuptools/command/easy_install.py | 2312 +++++ .../setuptools/command/egg_info.py | 752 ++ .../setuptools/command/install.py | 139 + .../setuptools/command/install_egg_info.py | 63 + .../setuptools/command/install_lib.py | 122 + .../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 | 196 + .../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-310.pyc | Bin 0 -> 1451 bytes .../_apply_pyprojecttoml.cpython-310.pyc | Bin 0 -> 13534 bytes .../config/__pycache__/expand.cpython-310.pyc | Bin 0 -> 18101 bytes .../__pycache__/pyprojecttoml.cpython-310.pyc | Bin 0 -> 16164 bytes .../__pycache__/setupcfg.cpython-310.pyc | Bin 0 -> 19683 bytes .../setuptools/config/_apply_pyprojecttoml.py | 377 + .../config/_validate_pyproject/__init__.py | 34 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1526 bytes .../error_reporting.cpython-310.pyc | Bin 0 -> 11587 bytes .../extra_validations.cpython-310.pyc | Bin 0 -> 1440 bytes .../fastjsonschema_exceptions.cpython-310.pyc | Bin 0 -> 2458 bytes ...fastjsonschema_validations.cpython-310.pyc | Bin 0 -> 68699 bytes .../__pycache__/formats.cpython-310.pyc | Bin 0 -> 8506 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 | 257 + .../site-packages/setuptools/config/expand.py | 479 + .../setuptools/config/pyprojecttoml.py | 484 + .../setuptools/config/setupcfg.py | 713 ++ .../site-packages/setuptools/dep_util.py | 25 + .../site-packages/setuptools/depends.py | 176 + .../site-packages/setuptools/discovery.py | 588 ++ .../site-packages/setuptools/dist.py | 1222 +++ .../site-packages/setuptools/errors.py | 58 + .../site-packages/setuptools/extension.py | 140 + .../setuptools/extern/__init__.py | 76 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3025 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 | 36 + .../site-packages/setuptools/monkey.py | 177 + .../site-packages/setuptools/msvc.py | 1805 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1126 +++ .../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 | 213 + .../setuptools/windows_support.py | 29 + .../site-packages/werkzeug/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 358 bytes .../__pycache__/_internal.cpython-310.pyc | Bin 0 -> 17250 bytes .../__pycache__/_reloader.cpython-310.pyc | Bin 0 -> 12377 bytes .../datastructures.cpython-310.pyc | Bin 0 -> 104616 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 27727 bytes .../__pycache__/formparser.cpython-310.pyc | Bin 0 -> 13230 bytes .../werkzeug/__pycache__/http.cpython-310.pyc | Bin 0 -> 36923 bytes .../__pycache__/local.cpython-310.pyc | Bin 0 -> 20715 bytes .../__pycache__/security.cpython-310.pyc | Bin 0 -> 4883 bytes .../__pycache__/serving.cpython-310.pyc | Bin 0 -> 30110 bytes .../werkzeug/__pycache__/test.cpython-310.pyc | Bin 0 -> 39293 bytes .../__pycache__/testapp.cpython-310.pyc | Bin 0 -> 9564 bytes .../werkzeug/__pycache__/urls.cpython-310.pyc | Bin 0 -> 32554 bytes .../__pycache__/user_agent.cpython-310.pyc | Bin 0 -> 1844 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 21713 bytes .../werkzeug/__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 31382 bytes .../site-packages/werkzeug/_internal.py | 548 ++ .../site-packages/werkzeug/_reloader.py | 446 + .../site-packages/werkzeug/datastructures.py | 3040 ++++++ .../site-packages/werkzeug/datastructures.pyi | 921 ++ .../site-packages/werkzeug/debug/__init__.py | 533 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 14255 bytes .../debug/__pycache__/console.cpython-310.pyc | Bin 0 -> 8153 bytes .../debug/__pycache__/repr.cpython-310.pyc | Bin 0 -> 8898 bytes .../debug/__pycache__/tbtools.cpython-310.pyc | Bin 0 -> 11546 bytes .../site-packages/werkzeug/debug/console.py | 222 + .../site-packages/werkzeug/debug/repr.py | 285 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 359 + .../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 | 435 + .../site-packages/werkzeug/exceptions.py | 884 ++ .../site-packages/werkzeug/formparser.py | 455 + lib/python3.10/site-packages/werkzeug/http.py | 1311 +++ .../site-packages/werkzeug/local.py | 648 ++ .../werkzeug/middleware/__init__.py | 22 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 703 bytes .../__pycache__/dispatcher.cpython-310.pyc | Bin 0 -> 2787 bytes .../__pycache__/http_proxy.cpython-310.pyc | Bin 0 -> 6875 bytes .../__pycache__/lint.cpython-310.pyc | Bin 0 -> 12751 bytes .../__pycache__/profiler.cpython-310.pyc | Bin 0 -> 4994 bytes .../__pycache__/proxy_fix.cpython-310.pyc | Bin 0 -> 6205 bytes .../__pycache__/shared_data.cpython-310.pyc | Bin 0 -> 9160 bytes .../werkzeug/middleware/dispatcher.py | 78 + .../werkzeug/middleware/http_proxy.py | 230 + .../site-packages/werkzeug/middleware/lint.py | 420 + .../werkzeug/middleware/profiler.py | 139 + .../werkzeug/middleware/proxy_fix.py | 187 + .../werkzeug/middleware/shared_data.py | 280 + .../site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 133 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4633 bytes .../__pycache__/converters.cpython-310.pyc | Bin 0 -> 8750 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5500 bytes .../routing/__pycache__/map.cpython-310.pyc | Bin 0 -> 30985 bytes .../__pycache__/matcher.cpython-310.pyc | Bin 0 -> 4546 bytes .../routing/__pycache__/rules.cpython-310.pyc | Bin 0 -> 27064 bytes .../werkzeug/routing/converters.py | 257 + .../werkzeug/routing/exceptions.py | 146 + .../site-packages/werkzeug/routing/map.py | 944 ++ .../site-packages/werkzeug/routing/matcher.py | 185 + .../site-packages/werkzeug/routing/rules.py | 879 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 191 bytes .../sansio/__pycache__/http.cpython-310.pyc | Bin 0 -> 3878 bytes .../__pycache__/multipart.cpython-310.pyc | Bin 0 -> 6645 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 17043 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 22421 bytes .../sansio/__pycache__/utils.cpython-310.pyc | Bin 0 -> 4582 bytes .../site-packages/werkzeug/sansio/http.py | 140 + .../werkzeug/sansio/multipart.py | 279 + .../site-packages/werkzeug/sansio/request.py | 547 ++ .../site-packages/werkzeug/sansio/response.py | 704 ++ .../site-packages/werkzeug/sansio/utils.py | 165 + .../site-packages/werkzeug/security.py | 140 + .../site-packages/werkzeug/serving.py | 1098 +++ lib/python3.10/site-packages/werkzeug/test.py | 1337 +++ .../site-packages/werkzeug/testapp.py | 241 + lib/python3.10/site-packages/werkzeug/urls.py | 1067 +++ .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/utils.py | 705 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 310 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 20226 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 29155 bytes .../werkzeug/wrappers/request.py | 614 ++ .../werkzeug/wrappers/response.py | 877 ++ lib/python3.10/site-packages/werkzeug/wsgi.py | 1020 ++ pyvenv.cfg | 3 + 1755 files changed, 329387 insertions(+) create mode 100644 bin/Activate.ps1 create mode 100644 bin/activate create mode 100644 bin/activate.csh create mode 100644 bin/activate.fish create mode 100755 bin/flask create mode 100755 bin/pip create mode 100755 bin/pip3 create mode 100755 bin/pip3.10 create mode 120000 bin/python create mode 120000 bin/python3 create mode 120000 bin/python3.10 create mode 100644 f.py create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/LICENSE.rst create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/REQUESTED create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/entry_points.txt create mode 100644 lib/python3.10/site-packages/Flask-2.2.2.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt create mode 100644 lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst create mode 100644 lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/LICENSE.rst create mode 100644 lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/_distutils_hack/__init__.py create mode 100644 lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/_distutils_hack/override.py create mode 100644 lib/python3.10/site-packages/click-8.1.3.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/click-8.1.3.dist-info/LICENSE.rst create mode 100644 lib/python3.10/site-packages/click-8.1.3.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/click-8.1.3.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/click-8.1.3.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/click-8.1.3.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/click/__init__.py create mode 100644 lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/click/_compat.py create mode 100644 lib/python3.10/site-packages/click/_termui_impl.py create mode 100644 lib/python3.10/site-packages/click/_textwrap.py create mode 100644 lib/python3.10/site-packages/click/_winconsole.py create mode 100644 lib/python3.10/site-packages/click/core.py create mode 100644 lib/python3.10/site-packages/click/decorators.py create mode 100644 lib/python3.10/site-packages/click/exceptions.py create mode 100644 lib/python3.10/site-packages/click/formatting.py create mode 100644 lib/python3.10/site-packages/click/globals.py create mode 100644 lib/python3.10/site-packages/click/parser.py create mode 100644 lib/python3.10/site-packages/click/py.typed create mode 100644 lib/python3.10/site-packages/click/shell_completion.py create mode 100644 lib/python3.10/site-packages/click/termui.py create mode 100644 lib/python3.10/site-packages/click/testing.py create mode 100644 lib/python3.10/site-packages/click/types.py create mode 100644 lib/python3.10/site-packages/click/utils.py create mode 100644 lib/python3.10/site-packages/distutils-precedence.pth create mode 100644 lib/python3.10/site-packages/flask/__init__.py create mode 100644 lib/python3.10/site-packages/flask/__main__.py create mode 100644 lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/cli.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/ctx.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/scaffold.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/typing.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/app.py create mode 100644 lib/python3.10/site-packages/flask/blueprints.py create mode 100644 lib/python3.10/site-packages/flask/cli.py create mode 100644 lib/python3.10/site-packages/flask/config.py create mode 100644 lib/python3.10/site-packages/flask/ctx.py create mode 100644 lib/python3.10/site-packages/flask/debughelpers.py create mode 100644 lib/python3.10/site-packages/flask/globals.py create mode 100644 lib/python3.10/site-packages/flask/helpers.py create mode 100644 lib/python3.10/site-packages/flask/json/__init__.py create mode 100644 lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/json/__pycache__/provider.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/json/__pycache__/tag.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/flask/json/provider.py create mode 100644 lib/python3.10/site-packages/flask/json/tag.py create mode 100644 lib/python3.10/site-packages/flask/logging.py create mode 100644 lib/python3.10/site-packages/flask/py.typed create mode 100644 lib/python3.10/site-packages/flask/scaffold.py create mode 100644 lib/python3.10/site-packages/flask/sessions.py create mode 100644 lib/python3.10/site-packages/flask/signals.py create mode 100644 lib/python3.10/site-packages/flask/templating.py create mode 100644 lib/python3.10/site-packages/flask/testing.py create mode 100644 lib/python3.10/site-packages/flask/typing.py create mode 100644 lib/python3.10/site-packages/flask/views.py create mode 100644 lib/python3.10/site-packages/flask/wrappers.py create mode 100644 lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst create mode 100644 lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/itsdangerous/__init__.py create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/_json.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/signer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/itsdangerous/_json.py create mode 100644 lib/python3.10/site-packages/itsdangerous/encoding.py create mode 100644 lib/python3.10/site-packages/itsdangerous/exc.py create mode 100644 lib/python3.10/site-packages/itsdangerous/py.typed create mode 100644 lib/python3.10/site-packages/itsdangerous/serializer.py create mode 100644 lib/python3.10/site-packages/itsdangerous/signer.py create mode 100644 lib/python3.10/site-packages/itsdangerous/timed.py create mode 100644 lib/python3.10/site-packages/itsdangerous/url_safe.py create mode 100644 lib/python3.10/site-packages/jinja2/__init__.py create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/_identifier.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/constants.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/debug.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/environment.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/ext.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/filters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/meta.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/nodes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/parser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/sandbox.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/tests.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/jinja2/_identifier.py create mode 100644 lib/python3.10/site-packages/jinja2/async_utils.py create mode 100644 lib/python3.10/site-packages/jinja2/bccache.py create mode 100644 lib/python3.10/site-packages/jinja2/compiler.py create mode 100644 lib/python3.10/site-packages/jinja2/constants.py create mode 100644 lib/python3.10/site-packages/jinja2/debug.py create mode 100644 lib/python3.10/site-packages/jinja2/defaults.py create mode 100644 lib/python3.10/site-packages/jinja2/environment.py create mode 100644 lib/python3.10/site-packages/jinja2/exceptions.py create mode 100644 lib/python3.10/site-packages/jinja2/ext.py create mode 100644 lib/python3.10/site-packages/jinja2/filters.py create mode 100644 lib/python3.10/site-packages/jinja2/idtracking.py create mode 100644 lib/python3.10/site-packages/jinja2/lexer.py create mode 100644 lib/python3.10/site-packages/jinja2/loaders.py create mode 100644 lib/python3.10/site-packages/jinja2/meta.py create mode 100644 lib/python3.10/site-packages/jinja2/nativetypes.py create mode 100644 lib/python3.10/site-packages/jinja2/nodes.py create mode 100644 lib/python3.10/site-packages/jinja2/optimizer.py create mode 100644 lib/python3.10/site-packages/jinja2/parser.py create mode 100644 lib/python3.10/site-packages/jinja2/py.typed create mode 100644 lib/python3.10/site-packages/jinja2/runtime.py create mode 100644 lib/python3.10/site-packages/jinja2/sandbox.py create mode 100644 lib/python3.10/site-packages/jinja2/tests.py create mode 100644 lib/python3.10/site-packages/jinja2/utils.py create mode 100644 lib/python3.10/site-packages/jinja2/visitor.py create mode 100644 lib/python3.10/site-packages/markupsafe/__init__.py create mode 100644 lib/python3.10/site-packages/markupsafe/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/markupsafe/__pycache__/_native.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/markupsafe/_native.py create mode 100644 lib/python3.10/site-packages/markupsafe/_speedups.c create mode 100755 lib/python3.10/site-packages/markupsafe/_speedups.cpython-310-darwin.so create mode 100644 lib/python3.10/site-packages/markupsafe/_speedups.pyi create mode 100644 lib/python3.10/site-packages/markupsafe/py.typed create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/LICENSE.txt create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/REQUESTED create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/entry_points.txt create mode 100644 lib/python3.10/site-packages/pip-22.2.1.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/pip/__init__.py create mode 100644 lib/python3.10/site-packages/pip/__main__.py create mode 100644 lib/python3.10/site-packages/pip/__pip-runner__.py create mode 100644 lib/python3.10/site-packages/pip/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/__pycache__/__pip-runner__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/build_env.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cache.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/base_command.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/command_context.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/main.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/main_parser.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/parser.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/req_command.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/spinners.py create mode 100644 lib/python3.10/site-packages/pip/_internal/cli/status_codes.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/cache.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/check.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/completion.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/configuration.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/debug.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/download.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/freeze.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/hash.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/help.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/index.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/inspect.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/install.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/list.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/search.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/show.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/uninstall.py create mode 100644 lib/python3.10/site-packages/pip/_internal/commands/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/configuration.py create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/base.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/base.py create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/installed.py create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/sdist.py create mode 100644 lib/python3.10/site-packages/pip/_internal/distributions/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/exceptions.py create mode 100644 lib/python3.10/site-packages/pip/_internal/index/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/index/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/index/__pycache__/collector.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/index/__pycache__/sources.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/index/collector.py create mode 100644 lib/python3.10/site-packages/pip/_internal/index/package_finder.py create mode 100644 lib/python3.10/site-packages/pip/_internal/index/sources.py create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/__pycache__/base.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/_distutils.py create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 lib/python3.10/site-packages/pip/_internal/locations/base.py create mode 100644 lib/python3.10/site-packages/pip/_internal/main.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/base.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/_json.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/base.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 lib/python3.10/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/models/candidate.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/direct_url.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/format_control.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/index.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/installation_report.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/link.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/scheme.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/search_scope.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/target_python.py create mode 100644 lib/python3.10/site-packages/pip/_internal/models/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/auth.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/cache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/download.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/session.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/network/auth.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/cache.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/download.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/session.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/utils.py create mode 100644 lib/python3.10/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/__pycache__/check.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/check.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/freeze.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/operations/prepare.py create mode 100644 lib/python3.10/site-packages/pip/_internal/pyproject.py create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__pycache__/constructors.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_file.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_install.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_set.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/req/constructors.py create mode 100644 lib/python3.10/site-packages/pip/_internal/req/req_file.py create mode 100644 lib/python3.10/site-packages/pip/_internal/req/req_install.py create mode 100644 lib/python3.10/site-packages/pip/_internal/req/req_set.py create mode 100644 lib/python3.10/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/__pycache__/base.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/base.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 lib/python3.10/site-packages/pip/_internal/self_outdated_check.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/_log.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/logging.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/misc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/models.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/urls.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/_log.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/appdirs.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/compat.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/datetime.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/deprecation.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/egg_link.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/encoding.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/filesystem.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/filetypes.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/glibc.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/hashes.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/logging.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/misc.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/models.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/packaging.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/subprocess.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/unpacking.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/urls.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 lib/python3.10/site-packages/pip/_internal/utils/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/git.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/git.py create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/subversion.py create mode 100644 lib/python3.10/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 lib/python3.10/site-packages/pip/_internal/wheel_builder.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/__pycache__/six.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 lib/python3.10/site-packages/pip/_vendor/certifi/core.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/enums.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/johabfreq.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/johabprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/utf1632prober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/chardet/version.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/win32.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/compat.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/database.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/index.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/locators.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/markers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/resources.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/t64-arm.exe create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/util.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/version.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/w64-arm.exe create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 lib/python3.10/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distro/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distro/__main__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/distro/distro.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/codec.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/compat.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/core.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/intranges.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/package_data.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/markers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/tags.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/utils.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/packaging/version.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/build.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/check.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/compat.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/dirtools.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/meta.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/console.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/filter.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/style.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/token.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pygments/util.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/api.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/help.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/models.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/__version__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/adapters.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/api.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/auth.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/certs.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/compat.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/cookies.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/help.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/hooks.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/models.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/packages.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/sessions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/structures.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/requests/utils.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__main__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/align.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/box.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/color.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/console.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/control.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/json.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/live.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/region.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/status.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/style.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/table.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/text.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_export_format.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_extension.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_loop.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_pick.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_stack.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_timer.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_windows.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/abc.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/align.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/ansi.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/bar.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/box.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/cells.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/color.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/columns.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/console.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/constrain.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/containers.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/control.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/emoji.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/errors.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/filesize.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/json.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/layout.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/live.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/live_render.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/logging.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/markup.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/measure.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/padding.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/pager.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/palette.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/panel.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/pretty.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/progress.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/prompt.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/protocol.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/region.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/repr.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/rule.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/scope.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/screen.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/segment.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/spinner.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/status.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/style.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/styled.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/syntax.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/table.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/text.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/theme.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/themes.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/traceback.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/rich/tree.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/six.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/after.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/before.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/_re.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/tomli/_types.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/typing_extensions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/request.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/response.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/vendor.txt create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 lib/python3.10/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 lib/python3.10/site-packages/pip/py.typed create mode 100644 lib/python3.10/site-packages/pkg_resources/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/zipp.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_adapters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_common.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_itertools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_legacy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/abc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/readers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/simple.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/_adapters.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/_common.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/_compat.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/_itertools.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/_legacy.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/abc.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/readers.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/importlib_resources/simple.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/__pycache__/context.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/__pycache__/functools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/context.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/functools.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/text/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/jaraco/text/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/more_itertools/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/more.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/recipes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/more_itertools/more.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/more_itertools/recipes.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_manylinux.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_musllinux.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/actions.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/common.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/core.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/diagram/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/exceptions.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/helpers.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/results.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/testing.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/unicode.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing/util.py create mode 100644 lib/python3.10/site-packages/pkg_resources/_vendor/zipp.py create mode 100644 lib/python3.10/site-packages/pkg_resources/extern/__init__.py create mode 100644 lib/python3.10/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/INSTALLER create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/LICENSE create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/METADATA create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/RECORD create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/REQUESTED create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/WHEEL create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/entry_points.txt create mode 100644 lib/python3.10/site-packages/setuptools-63.2.0.dist-info/top_level.txt create mode 100644 lib/python3.10/site-packages/setuptools/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_entry_points.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_imp.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_importlib.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_itertools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_path.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/_reqs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/archive_util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/build_meta.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/dep_util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/depends.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/discovery.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/dist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/errors.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/extension.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/glob.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/installer.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/launch.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/logging.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/monkey.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/msvc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/namespaces.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/package_index.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/py34compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/sandbox.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/wheel.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/__pycache__/windows_support.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_deprecation_warning.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/_collections.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/_functools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/_macos_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/config.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/debug.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/errors.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/extension.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/log.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/py39compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/_collections.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/_functools.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/_macos_compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/archive_util.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/cmd.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/_framework_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/_framework_compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/bdist_msi.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/bdist_wininst.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/build.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/check.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/clean.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/config.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/install.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/register.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/command/upload.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/config.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/core.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/debug.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/dep_util.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/dir_util.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/dist.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/errors.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/extension.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/file_util.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/filelist.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/log.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/py38compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/py39compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/spawn.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/text_file.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/util.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/version.py create mode 100644 lib/python3.10/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 lib/python3.10/site-packages/setuptools/_entry_points.py create mode 100644 lib/python3.10/site-packages/setuptools/_imp.py create mode 100644 lib/python3.10/site-packages/setuptools/_importlib.py create mode 100644 lib/python3.10/site-packages/setuptools/_itertools.py create mode 100644 lib/python3.10/site-packages/setuptools/_path.py create mode 100644 lib/python3.10/site-packages/setuptools/_reqs.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/__pycache__/typing_extensions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/__pycache__/zipp.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_adapters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_collections.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_functools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_itertools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_meta.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_text.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_adapters.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_collections.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_functools.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_itertools.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_meta.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_metadata/_text.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_adapters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_common.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_itertools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_legacy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/abc.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/readers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/__pycache__/simple.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/_adapters.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/_common.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/_compat.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/_itertools.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/_legacy.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/abc.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/readers.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/importlib_resources/simple.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/__pycache__/context.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/__pycache__/functools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/context.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/functools.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/text/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/jaraco/text/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/more_itertools/more.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/more_itertools/recipes.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/_manylinux.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/_musllinux.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/actions.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/common.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/core.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/diagram/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/exceptions.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/helpers.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/results.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/testing.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/unicode.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/pyparsing/util.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/__pycache__/_parser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/__pycache__/_re.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/__pycache__/_types.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/_parser.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/_re.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/tomli/_types.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/typing_extensions.py create mode 100644 lib/python3.10/site-packages/setuptools/_vendor/zipp.py create mode 100644 lib/python3.10/site-packages/setuptools/archive_util.py create mode 100644 lib/python3.10/site-packages/setuptools/build_meta.py create mode 100644 lib/python3.10/site-packages/setuptools/cli-32.exe create mode 100644 lib/python3.10/site-packages/setuptools/cli-64.exe create mode 100644 lib/python3.10/site-packages/setuptools/cli-arm64.exe create mode 100644 lib/python3.10/site-packages/setuptools/cli.exe create mode 100644 lib/python3.10/site-packages/setuptools/command/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/alias.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/build.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/build_py.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/develop.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/dist_info.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/easy_install.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/egg_info.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/install.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/py36compat.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/register.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/rotate.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/saveopts.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/sdist.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/setopt.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/test.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/upload.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/__pycache__/upload_docs.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/command/alias.py create mode 100644 lib/python3.10/site-packages/setuptools/command/bdist_egg.py create mode 100644 lib/python3.10/site-packages/setuptools/command/bdist_rpm.py create mode 100644 lib/python3.10/site-packages/setuptools/command/build.py create mode 100644 lib/python3.10/site-packages/setuptools/command/build_clib.py create mode 100644 lib/python3.10/site-packages/setuptools/command/build_ext.py create mode 100644 lib/python3.10/site-packages/setuptools/command/build_py.py create mode 100644 lib/python3.10/site-packages/setuptools/command/develop.py create mode 100644 lib/python3.10/site-packages/setuptools/command/dist_info.py create mode 100644 lib/python3.10/site-packages/setuptools/command/easy_install.py create mode 100644 lib/python3.10/site-packages/setuptools/command/egg_info.py create mode 100644 lib/python3.10/site-packages/setuptools/command/install.py create mode 100644 lib/python3.10/site-packages/setuptools/command/install_egg_info.py create mode 100644 lib/python3.10/site-packages/setuptools/command/install_lib.py create mode 100644 lib/python3.10/site-packages/setuptools/command/install_scripts.py create mode 100644 lib/python3.10/site-packages/setuptools/command/launcher manifest.xml create mode 100644 lib/python3.10/site-packages/setuptools/command/py36compat.py create mode 100644 lib/python3.10/site-packages/setuptools/command/register.py create mode 100644 lib/python3.10/site-packages/setuptools/command/rotate.py create mode 100644 lib/python3.10/site-packages/setuptools/command/saveopts.py create mode 100644 lib/python3.10/site-packages/setuptools/command/sdist.py create mode 100644 lib/python3.10/site-packages/setuptools/command/setopt.py create mode 100644 lib/python3.10/site-packages/setuptools/command/test.py create mode 100644 lib/python3.10/site-packages/setuptools/command/upload.py create mode 100644 lib/python3.10/site-packages/setuptools/command/upload_docs.py create mode 100644 lib/python3.10/site-packages/setuptools/config/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/config/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/__pycache__/_apply_pyprojecttoml.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/__pycache__/expand.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/__pycache__/pyprojecttoml.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/__pycache__/setupcfg.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_apply_pyprojecttoml.py create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__pycache__/error_reporting.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__pycache__/extra_validations.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_validations.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/__pycache__/formats.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/error_reporting.py create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/extra_validations.py create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_validations.py create mode 100644 lib/python3.10/site-packages/setuptools/config/_validate_pyproject/formats.py create mode 100644 lib/python3.10/site-packages/setuptools/config/expand.py create mode 100644 lib/python3.10/site-packages/setuptools/config/pyprojecttoml.py create mode 100644 lib/python3.10/site-packages/setuptools/config/setupcfg.py create mode 100644 lib/python3.10/site-packages/setuptools/dep_util.py create mode 100644 lib/python3.10/site-packages/setuptools/depends.py create mode 100644 lib/python3.10/site-packages/setuptools/discovery.py create mode 100644 lib/python3.10/site-packages/setuptools/dist.py create mode 100644 lib/python3.10/site-packages/setuptools/errors.py create mode 100644 lib/python3.10/site-packages/setuptools/extension.py create mode 100644 lib/python3.10/site-packages/setuptools/extern/__init__.py create mode 100644 lib/python3.10/site-packages/setuptools/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/setuptools/glob.py create mode 100644 lib/python3.10/site-packages/setuptools/gui-32.exe create mode 100644 lib/python3.10/site-packages/setuptools/gui-64.exe create mode 100644 lib/python3.10/site-packages/setuptools/gui-arm64.exe create mode 100644 lib/python3.10/site-packages/setuptools/gui.exe create mode 100644 lib/python3.10/site-packages/setuptools/installer.py create mode 100644 lib/python3.10/site-packages/setuptools/launch.py create mode 100644 lib/python3.10/site-packages/setuptools/logging.py create mode 100644 lib/python3.10/site-packages/setuptools/monkey.py create mode 100644 lib/python3.10/site-packages/setuptools/msvc.py create mode 100644 lib/python3.10/site-packages/setuptools/namespaces.py create mode 100644 lib/python3.10/site-packages/setuptools/package_index.py create mode 100644 lib/python3.10/site-packages/setuptools/py34compat.py create mode 100644 lib/python3.10/site-packages/setuptools/sandbox.py create mode 100644 lib/python3.10/site-packages/setuptools/script (dev).tmpl create mode 100644 lib/python3.10/site-packages/setuptools/script.tmpl create mode 100644 lib/python3.10/site-packages/setuptools/unicode_utils.py create mode 100644 lib/python3.10/site-packages/setuptools/version.py create mode 100644 lib/python3.10/site-packages/setuptools/wheel.py create mode 100644 lib/python3.10/site-packages/setuptools/windows_support.py create mode 100644 lib/python3.10/site-packages/werkzeug/__init__.py create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/_internal.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/_reloader.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/datastructures.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/formparser.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/http.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/local.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/security.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/serving.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/test.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/testapp.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/urls.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/user_agent.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/__pycache__/wsgi.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/_internal.py create mode 100644 lib/python3.10/site-packages/werkzeug/_reloader.py create mode 100644 lib/python3.10/site-packages/werkzeug/datastructures.py create mode 100644 lib/python3.10/site-packages/werkzeug/datastructures.pyi create mode 100644 lib/python3.10/site-packages/werkzeug/debug/__init__.py create mode 100644 lib/python3.10/site-packages/werkzeug/debug/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/debug/__pycache__/console.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/debug/__pycache__/repr.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/debug/console.py create mode 100644 lib/python3.10/site-packages/werkzeug/debug/repr.py create mode 100644 lib/python3.10/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 lib/python3.10/site-packages/werkzeug/debug/shared/console.png create mode 100644 lib/python3.10/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 lib/python3.10/site-packages/werkzeug/debug/shared/less.png create mode 100644 lib/python3.10/site-packages/werkzeug/debug/shared/more.png create mode 100644 lib/python3.10/site-packages/werkzeug/debug/shared/style.css create mode 100644 lib/python3.10/site-packages/werkzeug/debug/tbtools.py create mode 100644 lib/python3.10/site-packages/werkzeug/exceptions.py create mode 100644 lib/python3.10/site-packages/werkzeug/formparser.py create mode 100644 lib/python3.10/site-packages/werkzeug/http.py create mode 100644 lib/python3.10/site-packages/werkzeug/local.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__init__.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/lint.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/lint.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/profiler.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 lib/python3.10/site-packages/werkzeug/middleware/shared_data.py create mode 100644 lib/python3.10/site-packages/werkzeug/py.typed create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__init__.py create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__pycache__/converters.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__pycache__/map.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__pycache__/matcher.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/routing/__pycache__/rules.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/routing/converters.py create mode 100644 lib/python3.10/site-packages/werkzeug/routing/exceptions.py create mode 100644 lib/python3.10/site-packages/werkzeug/routing/map.py create mode 100644 lib/python3.10/site-packages/werkzeug/routing/matcher.py create mode 100644 lib/python3.10/site-packages/werkzeug/routing/rules.py create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__init__.py create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__pycache__/http.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__pycache__/request.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__pycache__/response.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/__pycache__/utils.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/http.py create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/multipart.py create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/request.py create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/response.py create mode 100644 lib/python3.10/site-packages/werkzeug/sansio/utils.py create mode 100644 lib/python3.10/site-packages/werkzeug/security.py create mode 100644 lib/python3.10/site-packages/werkzeug/serving.py create mode 100644 lib/python3.10/site-packages/werkzeug/test.py create mode 100644 lib/python3.10/site-packages/werkzeug/testapp.py create mode 100644 lib/python3.10/site-packages/werkzeug/urls.py create mode 100644 lib/python3.10/site-packages/werkzeug/user_agent.py create mode 100644 lib/python3.10/site-packages/werkzeug/utils.py create mode 100644 lib/python3.10/site-packages/werkzeug/wrappers/__init__.py create mode 100644 lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/request.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/response.cpython-310.pyc create mode 100644 lib/python3.10/site-packages/werkzeug/wrappers/request.py create mode 100644 lib/python3.10/site-packages/werkzeug/wrappers/response.py create mode 100644 lib/python3.10/site-packages/werkzeug/wsgi.py create mode 100644 pyvenv.cfg diff --git a/bin/Activate.ps1 b/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/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/bin/activate b/bin/activate new file mode 100644 index 0000000..3cd41ea --- /dev/null +++ b/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="/Users/leon/Desktop/python_Projects/flask" +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="(flask) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(flask) " + 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/bin/activate.csh b/bin/activate.csh new file mode 100644 index 0000000..c66b93b --- /dev/null +++ b/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 "/Users/leon/Desktop/python_Projects/flask" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(flask) $prompt" + setenv VIRTUAL_ENV_PROMPT "(flask) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/bin/activate.fish b/bin/activate.fish new file mode 100644 index 0000000..fe15aad --- /dev/null +++ b/bin/activate.fish @@ -0,0 +1,66 @@ +# 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" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + 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 "/Users/leon/Desktop/python_Projects/flask" + +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) "(flask) " (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 "(flask) " +end diff --git a/bin/flask b/bin/flask new file mode 100755 index 0000000..ec98429 --- /dev/null +++ b/bin/flask @@ -0,0 +1,8 @@ +#!/Users/leon/Desktop/python_Projects/flask/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/bin/pip b/bin/pip new file mode 100755 index 0000000..3895b75 --- /dev/null +++ b/bin/pip @@ -0,0 +1,8 @@ +#!/Users/leon/Desktop/python_Projects/flask/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/bin/pip3 b/bin/pip3 new file mode 100755 index 0000000..3895b75 --- /dev/null +++ b/bin/pip3 @@ -0,0 +1,8 @@ +#!/Users/leon/Desktop/python_Projects/flask/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/bin/pip3.10 b/bin/pip3.10 new file mode 100755 index 0000000..3895b75 --- /dev/null +++ b/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/Users/leon/Desktop/python_Projects/flask/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/bin/python b/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/bin/python3 b/bin/python3 new file mode 120000 index 0000000..1ec499c --- /dev/null +++ b/bin/python3 @@ -0,0 +1 @@ +/Library/Frameworks/Python.framework/Versions/3.10/bin/python3 \ No newline at end of file diff --git a/bin/python3.10 b/bin/python3.10 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/bin/python3.10 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/f.py b/f.py new file mode 100644 index 0000000..185ce66 --- /dev/null +++ b/f.py @@ -0,0 +1,11 @@ +from flask import Flask + +app = Flask(__name__) + +@app.route('/') +def hello_world(): + return 'Hello World' + +if __name__ == '__main__': + + app.run(host='10.10.11.2', port=6600) diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/INSTALLER b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/LICENSE.rst b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.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/lib/python3.10/site-packages/Flask-2.2.2.dist-info/METADATA b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/METADATA new file mode 100644 index 0000000..f644287 --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/METADATA @@ -0,0 +1,123 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 2.2.2 +Summary: A simple framework for building complex web applications. +Home-page: https://palletsprojects.com/p/flask +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://flask.palletsprojects.com/ +Project-URL: Changes, https://flask.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/flask/ +Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +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-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: Werkzeug (>=2.2.2) +Requires-Dist: Jinja2 (>=3.0) +Requires-Dist: itsdangerous (>=2.0) +Requires-Dist: click (>=8.0) +Requires-Dist: importlib-metadata (>=3.6.0) ; python_version < "3.10" +Provides-Extra: async +Requires-Dist: asgiref (>=3.2) ; extra == 'async' +Provides-Extra: dotenv +Requires-Dist: python-dotenv ; 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/ +- Website: https://palletsprojects.com/p/flask/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/RECORD b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/RECORD new file mode 100644 index 0000000..e5cc706 --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/RECORD @@ -0,0 +1,54 @@ +../../../bin/flask,sha256=ms8CYSDFT-oCkqRb_bQL6Q0MBwSG8TH4lxRTyqBsYmE,245 +Flask-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Flask-2.2.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +Flask-2.2.2.dist-info/METADATA,sha256=UXiwRLD1johd_tGlYOlOKXkJFIG82ehR3bxqh4XWFwA,3889 +Flask-2.2.2.dist-info/RECORD,, +Flask-2.2.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Flask-2.2.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Flask-2.2.2.dist-info/entry_points.txt,sha256=s3MqQpduU25y4dq3ftBYD6bMVdVnbMpZP-sUNw0zw0k,41 +Flask-2.2.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=Y4mEWqAMxj_Oxq9eYv3tWyN-0nU9yVKBGK_t6BxqvvM,2890 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-310.pyc,, +flask/__pycache__/__main__.cpython-310.pyc,, +flask/__pycache__/app.cpython-310.pyc,, +flask/__pycache__/blueprints.cpython-310.pyc,, +flask/__pycache__/cli.cpython-310.pyc,, +flask/__pycache__/config.cpython-310.pyc,, +flask/__pycache__/ctx.cpython-310.pyc,, +flask/__pycache__/debughelpers.cpython-310.pyc,, +flask/__pycache__/globals.cpython-310.pyc,, +flask/__pycache__/helpers.cpython-310.pyc,, +flask/__pycache__/logging.cpython-310.pyc,, +flask/__pycache__/scaffold.cpython-310.pyc,, +flask/__pycache__/sessions.cpython-310.pyc,, +flask/__pycache__/signals.cpython-310.pyc,, +flask/__pycache__/templating.cpython-310.pyc,, +flask/__pycache__/testing.cpython-310.pyc,, +flask/__pycache__/typing.cpython-310.pyc,, +flask/__pycache__/views.cpython-310.pyc,, +flask/__pycache__/wrappers.cpython-310.pyc,, +flask/app.py,sha256=VfBcGmEVveMcSajkUmDXCEOvAd-2mIBJ355KicvQ4gE,99025 +flask/blueprints.py,sha256=Jbrt-2jlLiFklC3De9EWBioPtDjHYYbXlTDK9Z7L2nk,26936 +flask/cli.py,sha256=foLlD8NiIXcxpxMmRQvvlZPbVM8pxOaJG3sa58c9dAA,33486 +flask/config.py,sha256=IWqHecH4poDxNEUg4U_ZA1CTlL5BKZDX3ofG4UGYyi0,12584 +flask/ctx.py,sha256=ZOGEWuFjsCIk3vm-C9pLME0e4saeBkeGpr2tTSvemSM,14851 +flask/debughelpers.py,sha256=_RvAL3TW5lqMJeCVWtTU6rSDJC7jnRaBL6OEkVmooyU,5511 +flask/globals.py,sha256=1DLZMi8Su-S1gf8zEiR3JPi6VXYIrYqm8C9__Ly66ss,3187 +flask/helpers.py,sha256=ELq27745jihrdyAP9qY8KENlCVDdnWRWTIn35L9a-UU,25334 +flask/json/__init__.py,sha256=TOwldHT3_kFaXHlORKi9yCWt7dbPNB0ovdHHQWlSRzY,11175 +flask/json/__pycache__/__init__.cpython-310.pyc,, +flask/json/__pycache__/provider.cpython-310.pyc,, +flask/json/__pycache__/tag.cpython-310.pyc,, +flask/json/provider.py,sha256=jXCNypf11PN4ngQjEt6LnSdCWQ1yHIAkNLHlXQlCB-A,10674 +flask/json/tag.py,sha256=fys3HBLssWHuMAIJuTcf2K0bCtosePBKXIWASZEEjnU,8857 +flask/logging.py,sha256=WYng0bLTRS_CJrocGcCLJpibHf1lygHE_pg-KoUIQ4w,2293 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/scaffold.py,sha256=tiQRK-vMY5nucoN6pewXF87GaxrltsCGOgTVsT6wm7s,33443 +flask/sessions.py,sha256=66oGlE-v9iac-eb54tFN3ILAjJ1FeeuHHWw98UVaoxc,15847 +flask/signals.py,sha256=H7QwDciK-dtBxinjKpexpglP0E6k0MJILiFWTItfmqU,2136 +flask/templating.py,sha256=1P4OzvSnA2fsJTYgQT3G4owVKsuOz8XddCiR6jMHGJ0,7419 +flask/testing.py,sha256=p51f9P7jDc_IDSiZug7jypnfVcxsQrMg3B2tnjlpEFw,10596 +flask/typing.py,sha256=KgxegTF9v9WvuongeF8LooIvpZPauzGrq9ZXf3gBlYc,2969 +flask/views.py,sha256=bveWilivkPP-4HB9w_fOusBz6sHNIl0QTqKUFMCltzE,6738 +flask/wrappers.py,sha256=Wa-bhjNdPPveSHS1dpzD_r-ayZxIYFF1DoWncKOafrk,5695 diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/REQUESTED b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/WHEEL b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/entry_points.txt b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/entry_points.txt new file mode 100644 index 0000000..137232d --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +flask = flask.cli:main diff --git a/lib/python3.10/site-packages/Flask-2.2.2.dist-info/top_level.txt b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/lib/python3.10/site-packages/Flask-2.2.2.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst @@ -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/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA new file mode 100644 index 0000000..f54bb5c --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA @@ -0,0 +1,113 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.2 +Summary: A very fast and expressive template engine. +Home-page: https://palletsprojects.com/p/jinja/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/jinja/ +Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +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 +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: MarkupSafe (>=2.0) +Provides-Extra: i18n +Requires-Dist: Babel (>=2.7) ; 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. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Jinja2 + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +In A Nutshell +------------- + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +Donate +------ + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://jinja.palletsprojects.com/ +- Changes: https://jinja.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Jinja2/ +- Source Code: https://github.com/pallets/jinja/ +- Issue Tracker: https://github.com/pallets/jinja/issues/ +- Website: https://palletsprojects.com/p/jinja/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD new file mode 100644 index 0000000..b821b4f --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD @@ -0,0 +1,58 @@ +Jinja2-3.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-3.1.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Jinja2-3.1.2.dist-info/METADATA,sha256=PZ6v2SIidMNixR7MRUX9f7ZWsPwtXanknqiZUmRbh4U,3539 +Jinja2-3.1.2.dist-info/RECORD,, +Jinja2-3.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Jinja2-3.1.2.dist-info/entry_points.txt,sha256=zRd62fbqIyfUpsRtU7EVIFyiu1tPwfgO7EvPErnxgTE,59 +Jinja2-3.1.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=8vGduD8ytwgD6GDSqpYc2m3aU-T7PKOAddvVXgGr_Fs,1927 +jinja2/__pycache__/__init__.cpython-310.pyc,, +jinja2/__pycache__/_identifier.cpython-310.pyc,, +jinja2/__pycache__/async_utils.cpython-310.pyc,, +jinja2/__pycache__/bccache.cpython-310.pyc,, +jinja2/__pycache__/compiler.cpython-310.pyc,, +jinja2/__pycache__/constants.cpython-310.pyc,, +jinja2/__pycache__/debug.cpython-310.pyc,, +jinja2/__pycache__/defaults.cpython-310.pyc,, +jinja2/__pycache__/environment.cpython-310.pyc,, +jinja2/__pycache__/exceptions.cpython-310.pyc,, +jinja2/__pycache__/ext.cpython-310.pyc,, +jinja2/__pycache__/filters.cpython-310.pyc,, +jinja2/__pycache__/idtracking.cpython-310.pyc,, +jinja2/__pycache__/lexer.cpython-310.pyc,, +jinja2/__pycache__/loaders.cpython-310.pyc,, +jinja2/__pycache__/meta.cpython-310.pyc,, +jinja2/__pycache__/nativetypes.cpython-310.pyc,, +jinja2/__pycache__/nodes.cpython-310.pyc,, +jinja2/__pycache__/optimizer.cpython-310.pyc,, +jinja2/__pycache__/parser.cpython-310.pyc,, +jinja2/__pycache__/runtime.cpython-310.pyc,, +jinja2/__pycache__/sandbox.cpython-310.pyc,, +jinja2/__pycache__/tests.cpython-310.pyc,, +jinja2/__pycache__/utils.cpython-310.pyc,, +jinja2/__pycache__/visitor.cpython-310.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=dHlbTeaxFPtAOQEYOGYh_PHcDT0rsDaUJAFDl_0XtTg,2472 +jinja2/bccache.py,sha256=mhz5xtLxCcHRAa56azOhphIAe19u1we0ojifNMClDio,14061 +jinja2/compiler.py,sha256=Gs-N8ThJ7OWK4-reKoO8Wh1ZXz95MVphBKNVf75qBr8,72172 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=6uHIcc7ZblqOMdx_uYNKqRnnwAF0_nzbyeMP9FFtuh4,61349 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=ivr3P7LKbddiXDVez20EflcO3q2aHQwz9P_PgWGHVqE,31502 +jinja2/filters.py,sha256=9js1V-h2RlyW90IhLiBGLM2U-k6SCy2F4BUUMgB3K9Q,53509 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=DW2nX9zk-6MWp65YR2bqqj0xqCvLtD-u9NWT8AnFRxQ,29726 +jinja2/loaders.py,sha256=BfptfvTVpClUd-leMkHczdyPNYFzp_n7PKOJ98iyHOg,23207 +jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 +jinja2/nativetypes.py,sha256=DXgORDPRmVWgy034H0xL8eF7qYoK3DrMxs-935d0Fzk,4226 +jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550 +jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 +jinja2/parser.py,sha256=nHd-DFHbiygvfaPtm9rcQXJChZG7DPsWfiEsqfwKerY,39595 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=5CmD5BjbEJxSiDNTFBeKCaq8qU4aYD2v6q2EluyExms,33476 +jinja2/sandbox.py,sha256=Y0xZeXQnH6EX5VjaV2YixESxoepnRbW_3UeQosaBU3M,14584 +jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 +jinja2/utils.py,sha256=u9jXESxGn8ATZNVolwmkjUVu4SA-tLgV0W7PcSfPfdQ,23965 +jinja2/visitor.py,sha256=MH14C6yq24G_KVtWzjwaI7Wg14PCJIYlWW1kpkxYak0,3568 diff --git a/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt new file mode 100644 index 0000000..7b9666c --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[babel.extractors] +jinja2 = jinja2.ext:babel_extract[i18n] diff --git a/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/lib/python3.10/site-packages/MarkupSafe-2.1.1.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/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/METADATA b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/METADATA new file mode 100644 index 0000000..485a5e0 --- /dev/null +++ b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/METADATA @@ -0,0 +1,101 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +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 Code, https://github.com/pallets/markupsafe/ +Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +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 +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +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. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +Examples +-------- + +.. code-block:: 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 + + +Links +----- + +- Documentation: https://markupsafe.palletsprojects.com/ +- Changes: https://markupsafe.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/MarkupSafe/ +- Source Code: https://github.com/pallets/markupsafe/ +- Issue Tracker: https://github.com/pallets/markupsafe/issues/ +- Website: https://palletsprojects.com/p/markupsafe/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/RECORD b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/RECORD new file mode 100644 index 0000000..2981cdb --- /dev/null +++ b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.1.1.dist-info/METADATA,sha256=DC93VszmzjLQcrVChRUjtW4XbUwjTdbaplpgdlbFdbs,3242 +MarkupSafe-2.1.1.dist-info/RECORD,, +MarkupSafe-2.1.1.dist-info/WHEEL,sha256=K9uXIc6oIZviKXIosvLmJ-uuGuBRuat3blAiqiaC13M,115 +MarkupSafe-2.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=xfaUQkKNRTdYWe6HnnJ2HjguFmS-C_0H6g8-Q9VAfkQ,9284 +markupsafe/__pycache__/__init__.cpython-310.pyc,, +markupsafe/__pycache__/_native.cpython-310.pyc,, +markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713 +markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083 +markupsafe/_speedups.cpython-310-darwin.so,sha256=8YpdqcIgNUJYRKaHXXLCMxrrYcusA5tF0m5m0VsAdc8,117457 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL new file mode 100644 index 0000000..40cc875 --- /dev/null +++ b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: false +Tag: cp310-cp310-macosx_10_9_universal2 + diff --git a/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/INSTALLER b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/LICENSE.rst b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/LICENSE.rst @@ -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/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/METADATA b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/METADATA new file mode 100644 index 0000000..a40cd1b --- /dev/null +++ b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/METADATA @@ -0,0 +1,126 @@ +Metadata-Version: 2.1 +Name: Werkzeug +Version: 2.2.2 +Summary: The comprehensive WSGI web application library. +Home-page: https://palletsprojects.com/p/werkzeug/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://werkzeug.palletsprojects.com/ +Project-URL: Changes, https://werkzeug.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/werkzeug/ +Project-URL: Issue Tracker, https://github.com/pallets/werkzeug/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +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 :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: MarkupSafe (>=2.1.1) +Provides-Extra: watchdog +Requires-Dist: watchdog ; extra == 'watchdog' + +Werkzeug +======== + +*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff") + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +- An interactive debugger that allows inspecting stack traces and + source code in the browser with an interactive interpreter for any + frame in the stack. +- A full-featured request object with objects to interact with + headers, query args, form data, files, and cookies. +- A response object that can wrap other WSGI applications and handle + streaming data. +- A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables + from URLs. +- HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +- A threaded WSGI server for use while developing applications + locally. +- A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug doesn't enforce any dependencies. It is up to the developer to +choose a template engine, database adapter, and even how to handle +requests. It can be used to build all sorts of end user applications +such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Donate +------ + +The Pallets organization develops and supports Werkzeug and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://werkzeug.palletsprojects.com/ +- Changes: https://werkzeug.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Werkzeug/ +- Source Code: https://github.com/pallets/werkzeug/ +- Issue Tracker: https://github.com/pallets/werkzeug/issues/ +- Website: https://palletsprojects.com/p/werkzeug/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets diff --git a/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/RECORD b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/RECORD new file mode 100644 index 0000000..b852c53 --- /dev/null +++ b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/RECORD @@ -0,0 +1,98 @@ +Werkzeug-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Werkzeug-2.2.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Werkzeug-2.2.2.dist-info/METADATA,sha256=hz42ndovEQQy3rwXKZDwR7LA4UNthKegxf_7xIQrjsM,4416 +Werkzeug-2.2.2.dist-info/RECORD,, +Werkzeug-2.2.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Werkzeug-2.2.2.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +werkzeug/__init__.py,sha256=UP218Ddd2NYm1dUhTlhvGRQytzAx1Ms1A716UKiPOYk,188 +werkzeug/__pycache__/__init__.cpython-310.pyc,, +werkzeug/__pycache__/_internal.cpython-310.pyc,, +werkzeug/__pycache__/_reloader.cpython-310.pyc,, +werkzeug/__pycache__/datastructures.cpython-310.pyc,, +werkzeug/__pycache__/exceptions.cpython-310.pyc,, +werkzeug/__pycache__/formparser.cpython-310.pyc,, +werkzeug/__pycache__/http.cpython-310.pyc,, +werkzeug/__pycache__/local.cpython-310.pyc,, +werkzeug/__pycache__/security.cpython-310.pyc,, +werkzeug/__pycache__/serving.cpython-310.pyc,, +werkzeug/__pycache__/test.cpython-310.pyc,, +werkzeug/__pycache__/testapp.cpython-310.pyc,, +werkzeug/__pycache__/urls.cpython-310.pyc,, +werkzeug/__pycache__/user_agent.cpython-310.pyc,, +werkzeug/__pycache__/utils.cpython-310.pyc,, +werkzeug/__pycache__/wsgi.cpython-310.pyc,, +werkzeug/_internal.py,sha256=g8PHJz2z39I3x0vwTvTKbXIg0eUQqGF9UtUzDMWT0Qw,16222 +werkzeug/_reloader.py,sha256=lYStlIDduTxBOB8BSozy_44HQ7YT5fup-x3uuac1-2o,14331 +werkzeug/datastructures.py,sha256=T1SRE_KRuNz9Q7P-Ck4PyKPyil1NOx9zDuNMLgrN1Z0,97083 +werkzeug/datastructures.pyi,sha256=HRzDLc7A6qnwluhNqn6AT76CsLZIkAbVVqxn0AbfV-s,34506 +werkzeug/debug/__init__.py,sha256=Gpq6OpS6mHwHk0mJkHc2fWvvjo6ccJVS9QJwJgoeb9I,18893 +werkzeug/debug/__pycache__/__init__.cpython-310.pyc,, +werkzeug/debug/__pycache__/console.cpython-310.pyc,, +werkzeug/debug/__pycache__/repr.cpython-310.pyc,, +werkzeug/debug/__pycache__/tbtools.cpython-310.pyc,, +werkzeug/debug/console.py,sha256=dechqiCtHfs0AQZWZofUC1S97tCuvwDgT0gdha5KwWM,6208 +werkzeug/debug/repr.py,sha256=FFczy4yhVfEQjW99HuZtUce-ebtJWMjp9GnfasXa0KA,9488 +werkzeug/debug/shared/ICON_LICENSE.md,sha256=DhA6Y1gUl5Jwfg0NFN9Rj4VWITt8tUx0IvdGf0ux9-s,222 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 +werkzeug/debug/shared/debugger.js,sha256=tg42SZs1SVmYWZ-_Fj5ELK5-FLHnGNQrei0K2By8Bw8,10521 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 +werkzeug/debug/shared/style.css,sha256=-xSxzUEZGw_IqlDR5iZxitNl8LQUjBM-_Y4UAvXVH8g,6078 +werkzeug/debug/tbtools.py,sha256=Fsmlk6Ao3CcXm9iX7i_8MhCp2SQZ8uHm8Cf5wacnlW4,13293 +werkzeug/exceptions.py,sha256=5MFy6RyaU4nokoYzdDafloY51QUDIGVNKeK_FORUFS0,26543 +werkzeug/formparser.py,sha256=rLEu_ZwVpvqshZg6E4Qiv36QsmzmCytTijBeGX3dDGk,16056 +werkzeug/http.py,sha256=i_LrIU9KsOz27zfkwKIK6eifFuFMKgSuW15k57HbMiE,42162 +werkzeug/local.py,sha256=1IRMV9MFrauLaZeliF0Md1n7ZOcOKLbS03bnQ8Gz5WY,22326 +werkzeug/middleware/__init__.py,sha256=qfqgdT5npwG9ses3-FXQJf3aB95JYP1zchetH_T3PUw,500 +werkzeug/middleware/__pycache__/__init__.cpython-310.pyc,, +werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc,, +werkzeug/middleware/__pycache__/http_proxy.cpython-310.pyc,, +werkzeug/middleware/__pycache__/lint.cpython-310.pyc,, +werkzeug/middleware/__pycache__/profiler.cpython-310.pyc,, +werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc,, +werkzeug/middleware/__pycache__/shared_data.cpython-310.pyc,, +werkzeug/middleware/dispatcher.py,sha256=Fh_w-KyWnTSYF-Lfv5dimQ7THSS7afPAZMmvc4zF1gg,2580 +werkzeug/middleware/http_proxy.py,sha256=HE8VyhS7CR-E1O6_9b68huv8FLgGGR1DLYqkS3Xcp3Q,7558 +werkzeug/middleware/lint.py,sha256=Sr6gV4royDs6ezkqv5trRAyKMDQ60KaEq3-tQ3opUvw,13968 +werkzeug/middleware/profiler.py,sha256=QkXk7cqnaPnF8wQu-5SyPCIOT3_kdABUBorQOghVNOA,4899 +werkzeug/middleware/proxy_fix.py,sha256=l7LC_LDu0Yd4SvUxS5SFigAJMzcIOGm6LNKl9IXJBSU,6974 +werkzeug/middleware/shared_data.py,sha256=fXjrEkuqxUVLG1DLrOdQLc96QQdjftCBZ1oM5oK89h4,9528 +werkzeug/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +werkzeug/routing/__init__.py,sha256=HpvahY7WwkLdV4Cq3Bsc3GrqNon4u6t8-vhbb9E5o00,4819 +werkzeug/routing/__pycache__/__init__.cpython-310.pyc,, +werkzeug/routing/__pycache__/converters.cpython-310.pyc,, +werkzeug/routing/__pycache__/exceptions.cpython-310.pyc,, +werkzeug/routing/__pycache__/map.cpython-310.pyc,, +werkzeug/routing/__pycache__/matcher.cpython-310.pyc,, +werkzeug/routing/__pycache__/rules.cpython-310.pyc,, +werkzeug/routing/converters.py,sha256=05bkekg64vLC6mqqK4ddBh589WH9yBsjtW8IJhdUBvw,6968 +werkzeug/routing/exceptions.py,sha256=RklUDL9ajOv2fTcRNj4pb18Bs4Y-GKk4rIeTSfsqkks,4737 +werkzeug/routing/map.py,sha256=XN4ZjzEF1SfMxtdov89SDE-1_U78KVnnobTfnHzqbmE,36757 +werkzeug/routing/matcher.py,sha256=U8xZTB3e5f3TgbkxdDyVuyxK4w72l1lo_b3tdG2zNrc,7122 +werkzeug/routing/rules.py,sha256=v27RaR5H3sIPRdJ_pdEfOBMN6EivFVpmFzJk7aizdyw,31072 +werkzeug/sansio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +werkzeug/sansio/__pycache__/__init__.cpython-310.pyc,, +werkzeug/sansio/__pycache__/http.cpython-310.pyc,, +werkzeug/sansio/__pycache__/multipart.cpython-310.pyc,, +werkzeug/sansio/__pycache__/request.cpython-310.pyc,, +werkzeug/sansio/__pycache__/response.cpython-310.pyc,, +werkzeug/sansio/__pycache__/utils.cpython-310.pyc,, +werkzeug/sansio/http.py,sha256=9eORg44CDxpmV9i_U_pZ_NR8gdc9UXFCdE7EAP1v-c0,5162 +werkzeug/sansio/multipart.py,sha256=Uyrg2U6s2oft8LXOyuTvFCWTLOEr7INVW8zFTXNwZ7A,9756 +werkzeug/sansio/request.py,sha256=SiGcx2cz-l81TlCCrKrT2fePqC64hN8fSg5Ig6J6vRs,20175 +werkzeug/sansio/response.py,sha256=UTl-teQDDjovrZMkjj3ZQsHw-JtiFak5JfKEk1_vBYU,26026 +werkzeug/sansio/utils.py,sha256=EjbqdHdT-JZWgjUQaaWSgBUIRprXUkrsMQQqJlJHpVU,4847 +werkzeug/security.py,sha256=vrBofh4WZZoUo1eAdJ6F1DrzVRlYauGS2CUDYpbQKj8,4658 +werkzeug/serving.py,sha256=18pfjrHw8b5UCgPPo1ZEoxlYZZ5UREl4jQ9f8LGWMAo,38458 +werkzeug/test.py,sha256=t7T5G-HciIlv1ZXtlydFVpow0VrXnJ_Y3yyEB7T0_Ww,48125 +werkzeug/testapp.py,sha256=RJhT_2JweNiMKe304N3bF1zaIeMpRx-CIMERdeydfTY,9404 +werkzeug/urls.py,sha256=Q9Si-eVh7yxk3rwkzrwGRm146FXVXgg9lBP3k0HUfVM,36600 +werkzeug/user_agent.py,sha256=WclZhpvgLurMF45hsioSbS75H1Zb4iMQGKN3_yZ2oKo,1420 +werkzeug/utils.py,sha256=OYdB2cZPYYgq3C0EVKMIv05BrYzzr9xdefW0H00_IVo,24936 +werkzeug/wrappers/__init__.py,sha256=kGyK7rOud3qCxll_jFyW15YarJhj1xtdf3ocx9ZheB8,120 +werkzeug/wrappers/__pycache__/__init__.cpython-310.pyc,, +werkzeug/wrappers/__pycache__/request.cpython-310.pyc,, +werkzeug/wrappers/__pycache__/response.cpython-310.pyc,, +werkzeug/wrappers/request.py,sha256=UQ559KkGS0Po6HTBgvKMlk1_AsNw5zstzm8o_dRrfdQ,23415 +werkzeug/wrappers/response.py,sha256=c2HUXrrt5Sf8-XEB1fUXxm6jp7Lu80KR0A_tbQFvw1Q,34750 +werkzeug/wsgi.py,sha256=sgkFCzhl23hlSmbvjxbI-hVEjSlPuEBGTDAHmXFcAts,34732 diff --git a/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/WHEEL b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/top_level.txt b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/lib/python3.10/site-packages/_distutils_hack/__init__.py b/lib/python3.10/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..f987a53 --- /dev/null +++ b/lib/python3.10/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/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..446d023596574760daf5961b3101ef42f8ed6775 GIT binary patch literal 7595 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 F{{fIWAoc(N literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc b/lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9e0554c91034fb954ed56e56204d9ed3933fbc7 GIT binary patch literal 242 zcmd1j<>g`kg1sAsl68ReV-N=!FabFZKwK;UBvKht7@8RuFfL?ZWJqBQX3%7c;*U?s zEG{W6$;>H^&qz$p_S0m##T6f)nOl%wR1zN_#hsELpI??*RFs*Lx{{#?WE`0Im82h9 zoLW?@pOc!Or|*(loL!P%pkGi~l98VmA5fH^m6}{qte=*XSe&h&lbHmSG1fCQ&@av` pN!2X?+Lf4|TC9&|zdp<|y@JYH95%W6DWy57c8nk&fb14v005$lMOpv= literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/_distutils_hack/override.py b/lib/python3.10/site-packages/_distutils_hack/override.py new file mode 100644 index 0000000..2cc433a --- /dev/null +++ b/lib/python3.10/site-packages/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/lib/python3.10/site-packages/click-8.1.3.dist-info/INSTALLER b/lib/python3.10/site-packages/click-8.1.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/python3.10/site-packages/click-8.1.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/python3.10/site-packages/click-8.1.3.dist-info/LICENSE.rst b/lib/python3.10/site-packages/click-8.1.3.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/lib/python3.10/site-packages/click-8.1.3.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/python3.10/site-packages/click-8.1.3.dist-info/METADATA b/lib/python3.10/site-packages/click-8.1.3.dist-info/METADATA new file mode 100644 index 0000000..8e5dc1e --- /dev/null +++ b/lib/python3.10/site-packages/click-8.1.3.dist-info/METADATA @@ -0,0 +1,111 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.3 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Website: https://palletsprojects.com/p/click +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/lib/python3.10/site-packages/click-8.1.3.dist-info/RECORD b/lib/python3.10/site-packages/click-8.1.3.dist-info/RECORD new file mode 100644 index 0000000..67ff862 --- /dev/null +++ b/lib/python3.10/site-packages/click-8.1.3.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.3.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.3.dist-info/METADATA,sha256=tFJIX5lOjx7c5LjZbdTPFVDJSgyv9F74XY0XCPp_gnc,3247 +click-8.1.3.dist-info/RECORD,, +click-8.1.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +click-8.1.3.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=rQBLutqg-z6m8nOzivIfigDn_emijB_dKv9BZ2FNi5s,3138 +click/__pycache__/__init__.cpython-310.pyc,, +click/__pycache__/_compat.cpython-310.pyc,, +click/__pycache__/_termui_impl.cpython-310.pyc,, +click/__pycache__/_textwrap.cpython-310.pyc,, +click/__pycache__/_winconsole.cpython-310.pyc,, +click/__pycache__/core.cpython-310.pyc,, +click/__pycache__/decorators.cpython-310.pyc,, +click/__pycache__/exceptions.cpython-310.pyc,, +click/__pycache__/formatting.cpython-310.pyc,, +click/__pycache__/globals.cpython-310.pyc,, +click/__pycache__/parser.cpython-310.pyc,, +click/__pycache__/shell_completion.cpython-310.pyc,, +click/__pycache__/termui.cpython-310.pyc,, +click/__pycache__/testing.cpython-310.pyc,, +click/__pycache__/types.cpython-310.pyc,, +click/__pycache__/utils.cpython-310.pyc,, +click/_compat.py,sha256=JIHLYs7Jzz4KT9t-ds4o4jBzLjnwCiJQKqur-5iwCKI,18810 +click/_termui_impl.py,sha256=qK6Cfy4mRFxvxE8dya8RBhLpSC8HjF-lvBc6aNrPdwg,23451 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=mz87bYEKzIoNYEa56BFAiOJnvt1Y0L-i7wD4_ZecieE,112782 +click/decorators.py,sha256=yo3zvzgUm5q7h5CXjyV6q3h_PJAiUaem178zXwdWUFI,16350 +click/exceptions.py,sha256=7gDaLGuFZBeCNwY9ERMsF2-Z3R9Fvq09Zc6IZSKjseo,9167 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=cAEt1uQR8gq3-S9ysqbVU-fdAZNvilxw4ReJ_T1OQMk,19044 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=qOp_BeC9esEOSZKyu5G7RIxEUaLsXUX-mTb7hB1r4QY,18018 +click/termui.py,sha256=ACBQVOvFCTSqtD5VREeCAdRtlHd-Imla-Lte4wSfMjA,28355 +click/testing.py,sha256=ptpMYgRY7dVfE3UDgkgwayu9ePw98sQI3D7zZXiCpj4,16063 +click/types.py,sha256=rEb1aZSQKq3ciCMmjpG2Uva9vk498XRL7ThrcK2GRss,35805 +click/utils.py,sha256=33D6E7poH_nrKB-xr-UyDEXnxOcCiQqxuRLtrqeVv6o,18682 diff --git a/lib/python3.10/site-packages/click-8.1.3.dist-info/WHEEL b/lib/python3.10/site-packages/click-8.1.3.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/lib/python3.10/site-packages/click-8.1.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/lib/python3.10/site-packages/click-8.1.3.dist-info/top_level.txt b/lib/python3.10/site-packages/click-8.1.3.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/lib/python3.10/site-packages/click-8.1.3.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/lib/python3.10/site-packages/click/__init__.py b/lib/python3.10/site-packages/click/__init__.py new file mode 100644 index 0000000..e3ef423 --- /dev/null +++ b/lib/python3.10/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.3" diff --git a/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22f49efa0764a931b4c0ecdf9a80b6bd91bf5e59 GIT binary patch literal 2625 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 X9V(&v<6q#`JH2#Yr0*RwbNBx@J*dXG literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc b/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e45d8a8e01f68fa734d8f969dbbbcc8e601521e GIT binary patch literal 16084 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 Y=}e_J&7j$G>fNL&<++! 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 Us5@&$O{x$>eC3 zkF5)mnUPtVYuBnzI(Pm_s>&lLj4o#;?2u@Ch@6z6EVCj%lqZEz)(L!KuADb5rcv8*tFxiOVhz5)2ox<4F0|7) z(K6G+((x>|rSp;*2&3&U#B71fi*I{hTfnK8=_2nv(so=H)86!~JSuYeg(*flDQ#~E zvEyEr9;|LY+`o6XXVX%D0KY#50@z-XrOCJ_krOA-g8k{4yCsj}TxF2|W$9Ry#kAd) zU;*vGCxp%ECgnHhZ#DY2|5~gQX|8l$CJf?VE_`$V8~JCy1o0z*&X767{>;4!S~wyV z{fICk;RZCi(&%|dk#7hkPoWTM*IgVWChZrCiG`;I0Tr0)O10w$OU~wzTf$d&AmAX=#b!^qGN8h zLGwUk3tsupVFaF&pBYm2I8bZ>_AC5f@cIU6>u4AW*Vg%LqD@?Ca znRRsKqaw{CvBd06v@r9`d8s-Drb0lCI4QO?P)}YOY=A-5x!`e$4=aqh zgSK~2Ae|cmn`k@`h_`(kL_io+$NmmH_7~&qPv)~fmVFnyuP&i>Z=|cU*Te}PEMN37cEaLN1O!KH+xrK~l!eg% literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc b/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2c39efc8a63cd45b9c5aeffd23121b757aa45b6 GIT binary patch literal 7677 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 YzVjV}<$a@1*NLp1NiI>XkSC7dwzj3;+NC literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc b/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a836f75db6162ca755849c889f6b6a13fae1544 GIT binary patch literal 2444 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc b/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01a53c819f068faa226d296889f42556a70c783d GIT binary patch literal 15202 zcmdU0Ym6J$b)FZ=A(#8&KD2sSV>t=DfxWWhq;a;gYFn0V)y~?nWGiOkaw*PG%Uv!> z-x+GPEZ21+r*YCcanKehnnzba5Wp=^AVpC$e^Q`8f&OYyp#9PL+4PV9v}g^qiJVyd zzH>Qz?5>phXDQ8{nLGD+?z!iD=bXFE@$sC2-@p8@Q2FaKhVc`=4FA%2c@$T8muVQj z;hS}%sPAUcly|FW$=xp6a(9Z3+*8Gr+|$Lh+%rWNcdMS=%oTH{;oH7bAKT0q^YWa+ z^LTMwp3``qC{D<8rarkjRh%-7z+InKPob7uFKo^fXH4TM!_WG;Hw-^_-73xo#`>H; zhEnsv>|w*t6%@mWOOa0rq5@vC)&1Fo?Nu!bV)avDfQaSlv?F>82I?+ zgh9QkxE<6Ol6MR>joZyjr(O&L6`raG&Bm!Gf^Z{hwobLSqqSzE^t@`W2bCy1Rjrr9 zjZ^j7<=&TvmL7cIR9K6G`&(dw@|7SwRjJo18>gZmr6b4)*?8XUEbJLczff$ctG6GGEQ7IbgjtSg*Xo)#OcM)p z!BCv*qOB%zQxizy)RqF7lEE!7f6w4jr2tHE9AA1w%A1bWDU1${Mc%!IUu-t^4J?Ja zB-4AGY}eQoLg``M7#b93E~JVb?!9+<1Uts;(J`sJkarKR_eiLM*_j?04Qt z3T761ykja7>m4h$mL3o$MvgGFP)pc2ce-8+qe^qLb>@CH$@b@s&d2vH4(A>&ovt@4 z<$8Dq4@oufA@@q0O(q&Dp}h1VPwYtDi{w6Bviu8XXa3+GMkY%tIk@^%ibm;Vl18_q z5-UE0DR5XC7c%Y}9&v!RXvO zGJFUesHReBh(1X*$P|Ykg-AoK_bDSnO=_QF|74^6;!M8pqYW49EUu6eSj#d}L+=#y ztAf_Peg{hrVafuf(kIvi+d4py>Jp2lI*RX$vm9)rycv{AajsO_Z2IjwpYx^CtL<{V z_r;82_i<6k=buw#)YuLq72A(Bw$&lNrY>(os0(w(cC8VKY*5^@>LkBA&w{yxV`BF_ zre2PkN|AZg5|hDR?@vZ$@quDGWa1h}%-K}Io=wl%`d`785^);s2IWmf;eQ}GD{SNA zNXRk1(Kb}hH^?p2h@uZ{&-a!1Yr>3SfbFk4P@t z&k?|a9F%vA;uvJiIAGKYR@J{4T#L>>cS)67tw6=;%k63vcZcg5J6P=?PH$|L)s;{P zxKiPENPd(`d?yeHxs@X0x+vGGSu?uM_swrmp^<7<*G3BHo3N@Ar@}UR)Xb6+4vSM{ zuV68yCDtQoPyuZl>erY&isT(L&X!6Qz=#l>JYWTK++(;z_08IX4~`u$zdlUZ#|V@= z+*j|Vkw72!2WqOvku$W52fcD^PqPj;QrhY)9MmHTdE4I9lWbeGy{Xv!f&Fm$&+_9_ zNDl5r=$2O^PAIk1gG{)~6$PUDB$H1ukc$$9sgW1oe7CT$$?=tVW(z zr;$90EA)`KhGjaYb<65q@@!3fU}dIE%U&?0v;f68Q&}skFo;Gpu#GlIY)(7$kx-iX zz-4M7G9zo(j;wX3YuvD|n>$t)g1c?1*)9}al=6}HWq?-MtS5YX$7tlDbk~S7sJ#g2 z;!-W{7*TdNCoPS!9fFueXGJ7WXX$LSUH834GxBInc-orqsL%rC!36OH0()9`EWL;E z8H@QivsMlTD`xO6^o^ZLIgDcK{Bv=ZX3ROInkvrK!dfGY%8g1Ow2#w4qr%N()tYhU zamqpnO3DSmJOR_c&IS(xcGH{XjX(qPk{-?HP*j9o&MBC#<=}Efq~y$kr7q%Y1=q-r ztNtji@cT#xVx?$jEq|UyCPathr-RgbI&fgvW$*;C0s)ehJlH9)fA}@E&ifdxlpq`A zwINuY5Ss|LPB7t*2a^y&6aJ(Kp{ah(ls_#w)BT)+KO;GXUY%KgPOKa(^5UU5{X!77 z>rv;Sr<-*@^rE%EtCU-?Z2}+b#7|zc>XjQu zCO{-UStM6Vor?M97sg(DLYYInwaqtWf{lba5T3Y`h? zD5ZBH1=g)~+c$4myD;T_`v#fE>3oa>OvZQn;l&xCojSY_H?8qpZ04YQxCU|B4>$|G zDzY_Kk$vD4O8D?~Tp@*7!FEjNR(~3L=C_{)0S>3(n?N1e2*!XGY?v6d<~qF-n9wd% zzMqnbr8^%TnHU%tqG~_cS2}lT_7({j2CXs>RZ!pV?;y2`u2q@IWh9GfVY@i@68T?b zn4%E*KM+9H7vuOAiVG^u*{)fDY8a&hN{rBf3r_qX%bCzYxe*r>5WfM_Xb1F&K!@w* zy8Ugq!n!6>=esE^aB3xXnj7Wqo95}8rgzgkv*_rJLW?GLA_!tphCPcJ;0Rk6EV*}Q zaKHW$E3DtE80(UB;#~So$E`G z)WvqI4qQb=p-2JQnu;Jot7z^AMUGMdliOn77x9%PLU!*O(7k!*zb(u9z_P7hxQ_L6 zCuO~l4Sv(jSU+>zS?K88Pp#w7%nq*flv!{U+u$0H{HXCC#TEVqw*07~$l6&aoAN!V z2}cwJl|d$OL@hvRR4wrdYNY{pnQvEfJ++XfcM%H2f%A-xGC0q&wtqMLidv=YZ-q)` zPcG_GVWf&lScN=1_H^ z6c4?T0%D$%e(Y=tecdCoSm?FO{!;Lx4rc!0M{*b=;b@Mar9&9gLUjtx!ef}@VLeCC z==e~7N7j$_sI14&z8(KA|AdV7m~Ufid_-Ns`jvlb8wN!Mm7-RK9zfsKnjeH-wcV&t zqm}EmXxodLJq_xWJt)h{h6mpOy{H}?067motyKjULB2;l_ng;it5!2agS7_g*1~2T zLdN%k#?_i?Ha3GswB&gg*J`2HY}B`uWu#}U}%anVY ztVQ^_tT6;$$`vUY0Q^CGqA|1p-zhrv6J6n#qw>;lBbe1PX6e^7>D0Cib$GJg)v~IU zFV{(7G~2uinOB2{_R45G@WDY8A%EGcRna-fgZ~&GS7P;|Y6q+LaZC+Cqp0pxRdW;b zLKRQ^fT4_w3$y2k2DHja=#GZrx2?A8GNN#;xyAN^YvoPIA+E#iS_+$+fLk?HX>V#6 z8=}dTW)xs#xO9YCx1-F9 zjoP*QTWhs?GiaC&|3=*@^+0inzeA7S4cpe&cIDV zFMpvA-}?wPwh<&yEHz?Ja>xlx6&%tv*Nv7VF(<3@y{Bqdv7^d;+19+wm;_~tFsX+B z!kB(gEz`IFZ(pJGpatKjy;z1?tOZ_D5`04$vdWUH9__>0Tf&Cd+)oaL;|`_ZN}^98aq~xb-b1B$4#9;|uip|!D4vraqoj7{r8*}D6g#kN zob3swARM8ejW&46veTQNco$)Pn=0S6`Vk5uY_s$53leA2Qy&ufiQMZ+K{3uKbjpcs z#vl^6h$5@R>2?dEHh>u{Zt5-M9cTu-Vg{q1zeNe*k(}dzL!1#FNeXGdL#ooOH`R#C ziq1%S?e1YK{{^1;66ZP?*e=Y zI~KhQH;kPe>W--gqWtc7lwY5SCSmO%)_TKoj2#E9P0{*WH?@)dmg5+aRkFXv9>>(< ze)>(bG>tNB#q?ov`>D4al;B9-9g-%NP=h_lAt!k9~`Xr>Fq zf>2=|~wT@0BV<^STWk-Nl!QuKhJ5Yx+n0 zIq4<8ehB@{%k#YSIA2YRSCRqD@tw(NVg2yV6w)I*(@2l*6ryA6$9HDB`DmeZxI2#Y zNOuD1(e7k)taQ9)?96r=;I_LM4|(OIU$l1ScIKlK>)!6&-MJfPceXos+UU-U$@Cwc zG{1D`9x*N%ul@sQdvg2VO^5;0cp2|oD5t-l#v5onR<-EJy<~J}d+ndl?d$g5Hr3&g z7H_e|x6SQ^ew(*O+Pu{Thrp(HN&hZ*239`iig{tKm{&pOHN$yzv*aF1qki8f_w@a8 zCo`DM+vcl}^m_k%(mV5p`{(K^7#qfl05HvZqD+&9pxlUC0PCd9Dij^08xRN3}K@6kt#&0$VCS|J2n?ba;ysF((tI*>>w*F8HJ#;Fx(Aad?=Lli~ zU_(PSi0Zb(B_ZTsqP^N6m#%xT2nOIeh)M}CrhHuXw$?B-VF2hXIYr@20vgS7!bgEV3`U$bBN*t04D1PqCit3vW7CXsJ=Z!ilrqFXgNeZ zjqv^DW$)po2l|V_E>>4HPNFJ>MF9+lbrZf?T?KqDMJWLWIJOHag+&a*^BW=(r z3l}dPhh(EffkR8vUsa)={w1UOnis;X((9)*t48 z>;%+JSrc$BiQ5180O<4u)gT%>QhmhpM3C6006i?j6u>;Kp?QK5LJQdJyLkAe=Be zi+7ydaLw2uupgNr*O+{C0hdHJ^$fYbI{+SP0`K;&qYs?O^I$!#6=A{NoDij>_}0Vq=@Z}U^`Ap@JN^n zZ1*-t@iitQ&$4}{`FrGre}}|+J%7}Z(*R^Jn7a()VT0sN_m<`4%=|4xX>1Du!M)`; zG>2Ua(N;!X<)8b0+V#wI23KmoOvXNNhTz+f7mjwWsh8-_ZxohoM~F z&YM%{fjJYsoTR+I=gg`9oZ8l z{q%RNZiZ(Tc5!z`TBetDKqTKEnj6Jt+=H=HXqbZm@)7l~1omem2uy!W9 zlVX@uFh)Mx8@8%-Cw9g#UX;IXg|9`q^_ksS#5E?bi@w$Geulc$cUfyEe+lLbW;*fO zMB{FK-!d_tx$PhH#xvbbg}?u0gDs;@J{jFmy;M?f3+9gWF)unBXIKv#yN58BDNuMp z{Rriz8z;IjC42ePjfFdu|3{XG5i(SsJ@^=(V_dgQqv1Yig#WsQ+3?@XxT3>dqdV1| zh5?p`;fk2@TNxmSTsej~IxoT7&>MJW05=)by`48XfT!mfF9R z4VKlwDLaAS1FmOZ*tVQt{hNwQ8$-e;SN*c_Gz?6va1Wj0cKnQCi!HC(F)*Oo%q z6cM0%QldwKeWn#HPBCUz`xe#yT6Z?7_I0vX!Yz|BSaTTEO;|w?e<19(*OaV*AOvfc z8~p(%1K)RFUA-WYk#jhaK;tAS(3_!fuwLaJ7Y}U@^iSsHIC^X=OuDZT0Ym>^%)pD- z(eUTX@el38#hIL*0j9T;KE$y)?1`nB*e4xH$UQ0Q8g22oJT|yQS(vZ46OCWJvvn+q zwGJ{=^i=Q z^96qA)MGO!rUN;1G-Mmlgc-6@(wa42p=qM<$+=GsS^&4@h~Z!x6UAA#9Q!WZUDN9w z599YKL3~q|`}zbhCQ+ng&YJG)I4AIWE|V7oI$`DB=aU0WXuW>ypR6T~G?O&_v(D5I z))UnoyRZscB`DnyJB?P&1g;7$Idw)y`>qMx0o=BZvmCzpmbqgi&*{Rh2FChWl-f;4 z8NBtJwDL`S4k&HG#`{#qjojU=E)UFsKm<@xZu^r7)?m(-Tcu<#AQq5({o^*z4Qc|LC_J=Eh(}oa;(2mMG50X zFMAeWnM4*v7wyLu$wDrBXJx9=2E2qd`3s;s%ig^%!eM7zGMQ01$zk#bUx1C_t}KqJKLCfuY5FU+ ze9g?&8V>1XHaC2>5vM9^C^;lN#Hdb(Yy5*WoHN|SrbhASE{GI@OHKk=f67*EHfi~h z-omn(#TcAP&@KLy4RLr;@PETi&4W+TdhCD_hWViMA5g#~xxHY7>KLp+yFQ=Wxfdb^Lu-YGs9|*N^Wx(xf&}LZ3qV1fN7iWYCai1?oYtOUw-}^TtDZ|K68HMDe5j2NK{purML%kk8jKnousGY$-xEbK}^XUX z6PA^|QhvYh)}tRYlJ*bsM@UO`=T_By-|v3+d)=>ELqo+3e!uhg$7{d)U75^(ivz*0Wvtcb;Wy|2ZY$LavE9WI{AzmmK5YM^!hP^yc z9*}qe@nX3saU1c$@}R^A8l~l-@{q)fjp5~y@`%I-5g#p&8W}IUG^Rc&HIJ9Kq0~}i zVtIRcyQCUId`EeQ#D^O@mv@zS8JQO{?ua}3R>mE@ZkBiBZpZj~RwlgHf0@#Jwy@hI*OxrcFo z7%3h_ipTI|(tQF?o{%~o$NdM~Be*{z_lIzQ)Sbfpl-wW2{W14R+&?Mzlej^}D;nS{hAv5`ruMmc2Cymf{tAQ8Pmp#M_i(U|T*8)CnM)9v0NQejH6+Ea^ z)#8SuowAJNTAW9vvtQ6x>H$<{EK_5DvM+n4=MijUvXJBMY`bb*?<- z;=MeR@)sO)-Lw|%Cg;q?jtB`w_5=8JQnJynOj@&s=orfbKYA~p6@jS-w7^x zPJri5Yr&~HEAfm^IiILD>V!4lsWx4w)@oky6w+U*HdZ~q=-{`YTFa8Z)>>X>qDH-m za+LG(T5ze=bn4BZ6}?x=s|8ZeR8jKIwVXQPV;PM=y|q<8U}0#;5yxM>SZh>$U2#XM zz-f3@AH`hqbp5SHqjeR4J*~?;iZ;!mJJZ!5P}B2G!0x;gm4qkti>ra>ETbmpqUZQt zFeRlh*9>48<)Ei%v>#NPH5rd&Y_8UWOV0fKY^&+b&+8(T7p$tLl)$lwUrwO~b>G4N zY6C0DT}!*^xz5Ek$MqJftBsDjr?J8=P0vRI9F-p3IarQtmmYLy)8S<8?8BzzRBJVF zB}npLs$#H}m$Z!?thHovlAdr5(vdkEBqLV6*Z`=sVo<=WNwb{#f=u%Kd@ZU&nKk<5v_8rF)paTXS8Y<_g1a8s+_Bryk=YhJH7%CTM3d<>dlqaXz0#_rMh1M zEl&MxIN>#~T&b!`qwWV4f2C0evQ%MS&s>doGX7-|;WdNH zKZPL3tY@wpOU4b;HEtR%5XgqH&bw@U7i8Cgmady>&w6Ib+Ay2uy0L+4-E?z5XkyXj z+yCi>Dh5~qq!wCgxk^-sk-`+zTB{8JgXgUJ-ok3b!E20W&}ucDMX%{8ByBDxokk*c zbfH?~c(|>a45JhlEhPfLD?Y$J0;ER0c6lno%2PqB!s;t-y%x+10I4b#GLm!dF(GxO z7ZXdFdFd=6ZnXx`1`H%En3{5!2ko!AuIElqJ0G5UGI^`UFkp(qSsqGu0HPW-foGFu zSQKEW5U}*4Txjtov?~?PRHYIQAW2Z?2!(}9Ri6u3C(VYI?==?GPS(NlZe`Ry{JH(g zG4xsa#~NO%dF-_3Uk+L;$5sUKR9;rCCEy$X*aFbV#+ z%wkEXA;fAHg80Wc!BwDb4{8kM$xSqLz_`12Cy_vlL!tX-nmcc#05TS!xmfDNt z%3*MT!9fNb4;}1BjHAlExl;KU?)*FgJ3nk#ciZD>!{a11YzE1XaZV%K^)4GJq=(r) zab9qp-YWoPRV=C)j|uDsM0wI}B7=IsWqYOWV(S3HoSK!k-7&n(rgFkRtQNLgEeQlzIZ8c^pbZ#DyeGMa;#o#t#bcauKRxH znv>3u^10_Kc&cL+=w7PBXhQFVY?H?88qiJO2jIQRbWb2?@9XJgce*~n>6)N*(uPLW z&SKK^1})24Q+0s(70ir=sE#R_)@xBJm==;q z*OhMGdV?p4eJr!8mt6UqnLzIZJg9u0(#G>jkc{t^Kyn6uqs>6Wm%CPAx zl7Q$uxrli76*}fR00gO2S}%om)z>jYX$5-mJ=VVr)uVX!1})J3UZ+Af3TD`dAtqfqJvn zSOxKs&U8rHA}3|2?UN}h=Vhd9&%YntC~y)npAfq_=y)Z zI&_eIku8(_@?^CCKb1U{_dUC*#iBopB+|R#LVGyv9bbh-jHPDIJw>4I>r1@H_#^@r zL55(D`8_<;T?d>C;I-0yV_LYZ>G{tHH8tg50%{l9Tnhj|jdscc=AG6>q0b`XAtgZ5 zhUuZens1TeBMJxY>kv~$v;{CmTqZCuSi1zo{MIs7N(*}oVU^1bpw+tScQToP`c_(! zFrP{Oj)LQDs$*?M_)-wq+2)m2O*Vl9f02}zI#CLF;uKsT1koz*(_pSi{daV)uZVP% zrpcwRdeIVz8qOsc;a^!s9gV*aAx}VxVJwBb58`R>dK&JUV($w`qS5L|dshl=-H9g6 z+1bfGYB$n`#Y$zl<*qhJ`dMa_POSodKd}S;|wMle1HKrh0wmhaR<|{ zj`P_wd}h4_#dyi@EG7al}%QWxUS@Y|* zWxj9aitp_j*p)R4mSNttqYKQ$on5=kA*MDvQkzI^4wy(4U$!}XM{2C0vaTN&=t*2Y zrz@7CQHJJOuIc3<^~$=|Th?`>oOg3%O2hFPtQ%pOlX;p`>`50xObn1<0kRN5=6dFH zhI#~12=}(lwt};<_{MXeSE{9M8JfWF#zrzbKa5-g9(l99tH1s!;o4^>3j!PJn~++4 zn1O(RjRgGZ zDW^j@gP#X)Q!ZgPM#7;ptIb+65uvq!TbYg7K03riTW8p4j>@{R1RA6QnFKDnEuhLG`v#G}=45nlu$B>H-h8B^zDu?m~p% zal^PtDM@AtQV`d87HuSbG^^W@#ZJA7Y1E65&55?_@<1Y=0ALM(G39c{vQF0;*X>W> zdY6D$L>n!my{EgCom_hdd(6F9@1dJA;e&WBL;5L1+Ih`>-!xvua9WwbSUYN95g2$A zpi9?{4ZLZN;7xYzpne09kmW)=bkp20UduF%tC*AHO}JKN5!1`9_& z92S(f(g2w?nU{eHi-N&r1*vaAGs4m<%{t`uo;(WkuE!g}Nop&q_9v0g=bW3_l2I~D zTqR=^2xKB_-fnO29;%4eogC_2ZPTpXrYMwzsyc;R^%8^U7_e=6@=h`)cylP4ts1xc zXvSpPUS<-(li!NikK*zPC3fbZvEMRt-B@t^j$*1BuC56&| zj$6vR7S>lzVtK?0d;{sX?G9k26>x7SlK%mhYi=lcFBj>eG0w(*bg7(=QfxRC{@p?0fz`b8wu+hn%Ace7SZMU&ID*gA1>B;uG22Va?e z`TV(==Pz7%{DWK*P|-vcqA{PZbnxS9#_L@U7E7ud}L2y-ynTKy2_F0O$gQ*5~sVbLcT zqxM*a9q3~dQDB$_6;sYH_*Cq5Oo}W;PT8;F@*hV~%;p78SjEy;^9D!~10up)>HSf| z%9`&FXE9S>wTtbYJp=#X0GhurcmC|`3tPgbBHa8gE>%I$-ql-C0*`8*i8ceUDqj3k zT=xR7ZHlS-0F2xefBtVE=*BH&3;O0n{|MXyJ)>KI&XzbOhkZT|{b126ARN@1MWF(y zT`ZMLZV9_QG?$9C!DKu8;b1XdZ>Gm;jF3ALeH+wdysmdID>n0WNKZBF;BmU#H)~e%Q63s`e3CZk=X!s&l5=_%7w1F&5Hx;Fe6oE1T#r;Uj z2@f~wm%Ug?(o+7U2m)iNfxoI&6xYxqB)&ehY;oNj0{w*Vq^01!DSm8Rt*%kTKuLAf z7ici+i*+qNW+Tzzs7*2w%3G`|7Y%}Rd%=O$tLl3d=u#mNgcN8V%q^5T%{9IWu0ca^ z8CrD+Mj+Rzx4jApyhtsksf$&RHkCNiZP420MVk~$!{kOpK?xX&7`o#Py$6tz%Z|K&Or+y z4f4a`?k-34YE~AM4jAWdGlR?5ax>7W8E7^@v!>LlsV*Ubsv`j9D)=mU(6QnLdyx|P zUo4IrZ=Qte$c(h-{uHV(N1IZpnWZdfRWqVhv$GxTvD7Ro(iBhHsB?TK)J?k2kv#nq zT*7#eJQV_UThzKP%JcxUld|Zd?m1e#WVD_^B$Y5yqqt+$v?*nP+RrVItWe!AiaAll z#go8hhJ(>`(e-x6lv1|VaJy4CDE z*bgVI+4fEp)&l%em^xh?cr$9vMmu|?I525QSI{q`66UpbRkcvGp1{M5r8|be&j;|# zHqd0k<$t?s$d1_qGE)9Ye$**JUdIwPRcIIXlhFlcq4a{~?m>d#L z49O5-FYD;c>p7~t*Nwkyej4iRbT}b&HK(3bi%6S36keErOCUR!?Dfb+Q#M(D@b#Sp8}J$fnGrRj*(n9I~oQZ>BMH3_EuH} z$X^~J0`}aB2BOf8F+5}zGR^5?UPbbqY`cv}K9e_#ck_4qT9*vgp15@bx^r<^IkpZB%*NJmR$XyeV7N0kuI9K82srGT4}EAMAS}0KSx)ve%r?BH@)3iGMzFMl zc&dOdm!jd7)|Q962HRJkW?~uPHO6E$K8n~N`%H9a6-JG5lXx?4=I`Wlwvm^Zjo3JO z2KfgX6~Z)#%5tV*f2}>-4OCrIgo0CqN^yy6(4b=p$Ofp>6m$uWyr7FXeA}1=P+Jsg z>+yLJS$b#b4Lm!Jf`yA3@7#Sf-=suL%Dt{joKE_k@GSU(WsnDGWR{IDfO`x~T9GWl zie$sW-<;b0c>@9^itOxlOXHH}(A&n1{LRc440)I9e3yuyfJ>MfE8DIx)tqoP`Rs&H*GFH7ap3nYa!)aZFfHOZWepkek4vMi6v?OpF4b#tWYy`W-}pMX~zH z0CO4&JMkwlXP@qnwi#hj#?+^F7V<3On$V~LtE4h>mK6>>OS_(HE9%5)R4*iq`Psdh z_TdPKy9MPP2r|yLbz6zQq^%|0)|-&SZPi|=%b*B>5bioMskaz>CxaCIeIBSJ%&u?);xeq>qE%6>-ox%FAh$3n?7z)rEg9fX6LDir&pXle;GW3_e<< zb{08Z;h%?@685<^p3^EA*1F)vH7`Bl>bFI{abZO(ymj8)CbB@yOHa7lQO;;23*6!E z#NC+i%Hu$oyF>dltX$_{QCWizw;))tGF|0!I)MN@%h~=^j6M)0bR`V#UYjdx!UPWP( z&e;p+oDYBK$>ULdG0XcZwf361TqD!_MBJ$-;)F+>wR^MVRn3%Z{bLU|4$XcyCw}C? zIq{x>;gBQ(*~r#pJ{j35tWVgvV2I~ajczn3O<(kO0i+4qGJ?ho_ZWDQd?cJUq=_Ob z0BHq51-N`|=HgXh8KIka1hWiw9^&`7Y7|~q5RXJ%kU5pcfRpl}qlP6A1n=+}m_p+F6CsgENv?d?g0451Zu5<(TXr}h3lk=*84?dq2#&*j={X!-k0=ZvmBb$8$y;Y3cY{_yres%;1bu+k>!YO5p&>A!BQU885WarTdd>t*cp>xYB4jpJ0G^!b6OOzP*i<101M-v{ zc`@S1Epp_v^Nl$2+^l*Nb+?bEY@OQzLLt*9L`f%RdsD9{aDm4jAi3{E>HUp_CFG=P z2p&`y8RxucaQRD&3G@gh^%>qi!+>z8zMTPcZ_WzJtMWiJQ4lc=MvH$lDH35P;50st zND;J1(JXF(Gn8ai`$Vzwv&%O)! zv>Kul8$^8FBP?dyeQ3CoESV6b3Art4I2mRcVRl~Aa9dJtZ1_tYpM!`9 zNOYheWTB|5oNka2`Vm8Lw^T6~Q_4xnNYdZr6-b9E|}GO`L!BC?4( z{^3Z!mbn4GStN%RRulMU*L=r}S5u5|Cc)qzN>@iDKM|z|4DH^Gnn}wttO`?F8V+_m z1-tOQY&bELhJVGFEF7WTw^H(cFK3JfHCh>OLAjQP^*!lo*!A3P@7-+RV!hhzWS{m` zc!Y08d7(u`wfZQVaf-o71_DPZc25EOd+_!z#%(EPU=GlueuYgD)AT_MF(iNfKSK~h z%z%M^uu2**aq^5%0u32xY{HO^@@ zZnT#fW;yN%N*tBg7-F=iDK6L|TJUiBvBUe`h!u?mktB38YoV>#HPEU##Q z&C9sxfN`#70_?k7pajKO#R1z-nB}Zv%cx`_vdvViMCoxWr~V33tG~+NuQB)m27evF ztw^W4)%%`(Q8>jP!3@94Z7^>`Xoi1KjO_01WJ20>AxpNN8($Wee*{5?iUdjrEG!XD zae?9D##VqmYtBGVF_u8AKZrb&c1i(-`PCI}&0BU*ZABgZG~twjI;u|6fBE;ULVI6d zZ@TCv2e~%0*y!5hi3B-e($!x?1Y}gE0ZBV-0Dw&}b+Q*@Uq`38v$yskW~rU)Fekyu zE*P3{8ke$=)aij>nqzokt4X{akTgX}Q$QNZw1#;i zc`OYf4ie-D`%HZ};i6a3)!3WKjMa~zJarU7Ip4tHpL(;LU&P<)wO;C(jrua-<4Hv9 z>?j1qqr|9pidp?PZ^8N!N3&pm2@GfBpT@STDqusFTUR2rZbxo*6k=ZJ@uBoR(g8LJ0SZYmZSUokG$n0;I)j0T&!yc$T>WhZ zf0seJD+#6bx9}|FL=y2}YIgQbjRvSLB*k&2E{JH>|4sy0FIc^+5TGGusG@5&Au-=D zT+jkv6l(p888St93-f!VJB(OX?RRrX2T^5`4#uKUx~w`HmBKY@sAr-(u1%!U`quSq zQaV>)p?w&K4siyDjCQinKZW|}s=82EO##&aH zVE$wyh%B!|v$ayrHWcz3AQwcu@;IF4kO%Sw4MGz?Ou*uqsy5fUX;GWJp*%(*Kijr7m_ugD{OYF=+%_Eb)A)-H zaa&VV^=kT=t&drAdDR0VB*y=Uz2meG8_wo?nI_C{xYeMs`}N0OUt;7LU6j0j7GO|fp6&e{J3(NHAz}9H?A*P%qxX>@(Df@8d^r2bK3#UDWUqac=1)#@h*31VRIl)SA5zxHcW96mrq#h92>ff09gv{ z7{$y&hIX2PYL>-D^Urfbta1gN$3Y7Pbv2B2oN16PRao4}(P<3GyhgM{nbl|yg{_Z1 z-{`r5yhUXOE2Y$4M|L}ZK0@Tcr}OjJ*5<_^2+^t>j)$yM4zY+`5v7U|P8W{>kR7hj zzDjnAsy4hz@b?r^v=k|XX-B#7Jq4*=lg3gwLI|WJ?UdvF{z^-qBTF`th#!hDd$Ku6 zA3A#=dl>3M`lRUCatudj{d%-5NJgfT4Cn)fE^b0vDJ;u)zzbu^gGkt-qN>t!DYZ+S zpxz_q&+*u~;MuML-~k^Q*?0sXh1CvAAO+_R*B*)%gPuf{Zcu**0Hk**Sti6c@sDvL z#u;4Ncq!{+bHSDZGI1w_Jsp<5KZ!IQK%MM!qbNX*URw}k*k*eq2E8f0$8EA^KEk5X zg(FBy&{B#c(>3$+NPHJSoR~gZ!#F|$!AWxQ$Ou#Qt)VO)p2Vg8Ap#r-89qZKncxrg zCBAzw+>tx;(z)mEgFW_PBsBKe*jX!N4*nDkeCd0Tzi|&`@y%h7t-YTtyrRDG5tT26hPMphGamgsCSOSGt@Q=RgF@d^f2obV#D_04NHN$;xP2N+LHujvZP@gR?zXq3izN|UY=*h}m@|~tkF*1D z3+xvK7QcuDFcmAEUxnY3<*0F6q3}~|90!u}2s_sv>ui=lrurF{SL!8xQbe9mq8h2D zbg1C<*O0qo?~w744dfT_;s9%>P(}!%5fGJ;JbWucbNFiqM-+4RA-|YtiVsr^ox(B7 z1mA}Ro~pz_@NYm^ONK0A%Fg442fkpQXj64UGbEV788AeFc_Y*&FlNL%7_Qe!{^XwhGw&MrhQ;bA#l|3DcI{cCo=mH^+MVz*A6JNJ^V?nSmy z)>OK%-oUdeD%P9sj_yhlnqAFzXHE0}GG4sIhLde0^!3V(acpN?G1Yw`ZS0j-&Yl)X zqbn7C%xZPD?tX)yMgX3{<$nr6D!BtWW>MFsN}4z$ce-IfZ(vcPmmK4>;$wUOIOyky z<(8n?qor}5&H##35LKD>{w-mKJ(^O#jzr*k{ssPs`Yg2gT>W$2Z=x{R9By>>p4lVV zT;k{xr`y>QC0d~Dc%Y9`uHs#25O((s>jMLi`j>2?)VUSxtR=9sr@x*DfS=z)4c>j= zXG}3wAN(X_+P`BNkxxLfzOhHZr9#;jVl4-9Ee}mZ!Q;8x;?kfu0FrGWi4`Trv$umD z&*WIpNAUD*j^}akZW#KAV(b}E$T@nnEWt`>jL(s#gcCf}I`G_$em21}-R&rIhs1Uw z#PUvV&#DtK9+d&dO99s0HSiK8oQJdRd~^Z><{MEus^9aU_cLU zi{9)gqk`m9`&jW{tO5@SS7A|9UBJqW-ipHlDGFXj>aa<4ovST%8CAvpe%NNPc;J|M zVg@@ulH9X#Vt`a_MC|nZ{L$#_OC+SE#Y}*1u~&%D7gL|l6Zi>;&%2yT+~;XAr3?H6zWOP-pfnnC!A|`hZQ!w9v7fqbzX;kUqp&6)F1CCR)KOpH%bV4c}-uf~O z*Xz)#U_#NbRdDjr6wwap>^V9dgp^mG-64sFmLNAR#aNg0hDQor99n{40iKA&F9wDh zQ7H-A9bA3_coLUP0(F}WE3AWb2gJ(~J-kdgVra&}By?&IMbZ-_tfS2x-~n5vfGvcB z3mzQP-~$&gI8_D@08v`VRp@pS67kflhaA>yuVF(hDxinvwt{dF+Jn=ju`7h9lntc_QOfwW2 zIdBAaBpS31FpIkg1al`+bR$ghLkvnJ}hPSnGk4%1CGV9=?ONrM7*5B@0xWkjl926W!&xFR+IkaAem0gI%{0`zhLl}->w`(=7coj}%g~;%y*zRE@ z1s_NSo}8gW`*%qD`;tG9!k1d{8C-rIG+p}*@+M#fO@B~gBpip=#n%G}L$Jm?oCRk1 znZN{JVlKg$iyD2c_r_n2#Q=!LoS1)!l2{#I&)$I2cWLmZff>xv_ALN0x>+t956VGx ztn+;eis3ot4Tg|=_&Vy2^CwS7I-gpZV07(sMrNY`Zxp-G-Z9q-#&2w6tEr4xFDy+! zon^%Y?W^K>Vx#bxf@bF#y9)0VP}uNrPt^@`+~MHMS(d5jKJ>qC~93toV347))+F0v+) zX7qxGvDCKBX#&}dASrXSD{rEAU}V_=5%72VWXKr!IX>Nqu;}hWiMu5R-wIJmTfRs@pYQlm0lhJ} z`@CU!x6R!z{N2N@15PpJ?+%96%b3mTj{+wM-9OJ;=+S6!C^T?=xelT#Cdy(5dITn& zD5ZY2^V;ZW1KyKV0vVO4(!kdUJxu7P+jdoNt%6CTLx-4G6I>DL?^tC-WNU08O`=K; z`Gv5AO^|qdZ8c*Y5#a~#8jfz^=mL8rsX{bURL6RBijKO~tD{s9t-q7;=T_zG01 z)GrE6@s$S}lGJ_dqjG)@vcB}VM^smAjgpij)d(X<#txjoszQA#?m4xgK8K6PL;TD2 zl@%Vv=)iXDL8W!Mx`wkDbP(u7^e*_INW^!~27n*UF%Cf@4;9oHvv~4Fqd-vwKr`abIZrN6If30^ zy?RTdN?K4c})T*f|66Ujr;)+!j%h(Fe>uyYvhBvCt9 zGJ>Tnu6i&zMK9|~u4#JmNIYILjeJ)_e5^x<4F@5Tk&L2rQ2TgG z$8wpC?~~P|3*l1bvPoJoAAOVHh;!NVR-z9t9D;C1%L9^5)0;Co2bC2&LB6(WYL9Sli@Oo<^DZl-@2 z-XEZR!P6p%e!MZ&2l?LrAl^Xg9lya{Hob$d4fS79e>jk!GxgtbKRKxW5P#GkF?g53 z|7P&N7<`SvA2awW1JYAUF_=IA3w9ybdvZ%gDI(4IC(I*-^+>_VV^3s3r?8}aNn19j zVF`433CDgwe&LG)!KH-%?zdau7?b-zVcLRpb0!?)MEhQ`?Zsahu)hPYF*0<9gka0g zZ~!I;dKvY5Cf|~IKh7R=2)nJIEhB#$=8|w%jh=R~@<)-jkCkUnXK)FPhrVc5{xB^0 z$e6-gh<})W0~5B9JA>>En6}W9ndngXJcs9x;5mGgrO$6*EaE#YP$}qXzlfSNtx8H( zeT6{{0U0?F-FWIrKI@*~aJ<&?AT6!PLcuzMucnW(_v1*r1I#~0AYXhBp;f$NneCm@ z_x?N`JRyY#=>d~2-7x1r5eED^*e?2P;TW{=#f2pUAw0NT5f5+v@8gN79(GOGhi5nP zfdzMtd5i@-!`&#{gzX=E#TD=r{uvN2z#-%zFy{knACJ$bEEWB40)vh+ZyI^9;iBj) z1w&kOOT#FAgcjXWE=H96V9d0~4kVW{_?U%#V+>6FIQ$M=Mrq8SyI+2kz0H3cIVYl= zZ$~+)V!db0$hlqpING#h-3qLwoi|PY$D_Q32gtii{c4hTH}d{!l-GWMynEE|OI`!@ zK7_m&f9dVO{qyQE1}|NloiyLYv}TT~-z5|<+J59s(#ab*`$ifNQF>8H_H@DZJom%p zrv4Q(?B6T{s1{8XP9+5%N=n=~M5?BmlE70i!{4OVi1dj!j(ewyH=3#TbfXNB;=D*4!QIlzPJnHNs1Scm*$wh^U*FxI zO`llrjTgG_C+u(RzG$~g5hjwaVQnD?5~C3`at4=Js&>hNh+nuGv;MG~g`Ks9QzwuO z!6pZ%JVZ8>uf7cs{=X#~A`0#l3kl;!LOUVsV#1&ff*2ehZC05nW)4X}{h1IT>7xxK zmehYk0Q2@lgrq4X(n_&9;UJS8V2}!vgiz`MYYJ?>mtak(DGf~knA_U~$a-W-183&u z&di-Tv!y&qRy#>I^*NuQ;LyHg>L5zg= zaPlcf8Ru;$2vYZ)6Jc(S-Y%;< zF@AF$+S`jByl2+2#2}5)ibZT4;L55iE0AGSweSd9zSsa;FU*)FrV>vS_K_YJy2fRG zJ%MUQd?LZSCZB?%K2~(1_&%O!=8!28yl|(3&rezR_(T~$%m?-!y1fNYzR^NH42iW5 zPe^efZr1AmG>P~WgJHs1sv;wuqNq8^!^g~}bUqS=QC%7pCH4&LFhyj1E^b1jm(nQc zB)4p}qtEU}Ean;XvRB=RZpN-P#o6dlRuprRGI&vA@WC;h$wJ>Cd(b{Xs_`ccwU<(S z9|gze8d|!*QleTTEGXkNjaj14B5^7z1E+m(^^YEhMwhEcPr8b&mzjj2neC(T0XKSg z;V#YH1>OP;dH@5D2YMegQFgXQGARBrgN5q?E@3fZ&rRB5ufuZ_?IRU~m`=7t=Dkdcomfk{Mj$I|R@V22fmZKZ0kN z-fzbrnH05IMceT9m*R@>DZoKpk$k^GIm~*1!993U?(&=w6r$}J<0jxNGS)D?hvL*P z{fzHN)5OmKP7debIRwgS(1_W0%(vlg4SZwP0I&Y}47>tr*IKst9>IiM7pNC+fQ8xi z^qXLRWF>ECVInvdNXBCyu-ZII(ujm|!?_BXshm-rYJc-LoEIBKlo=is?YQP}fH5f_ zLo7pd5dH6(8x9Bu=4lR$gFql`Fm|g6_oe9e^=uEU2_(SmTvp{U0q*Z1t70Ja{&*96YV`_vg8D$_y zLYgBjc@*h>g)QM7zbHwY;Fwx6zmB8K;@>j=HK*7f>T2T_Zsdfvn?Ye=4&RMvHP!dA zC1VV>r1Q@5E!RxP7gbL3maW@bd5CX|XZ|MJ&bcGS_vjEDk>uc50tc~sUCBWe$n=VH z5*8wHv=+~C1;#%PDhW9Dz=s(O5ENV$BEsN=BLFyTh`I2T4>1m*&5Ha@U!s3&N? zi%+s<@dig!qc@Ku28;4_9MZ=!$}|Tg&KQImvb3;lHcT!!as59H3lD6Wu-V{~Jj#A< zUBop(VKw99h`zMqV}VT(PB4HL{kZ@K2@xMe{M7(olR$h3@z;Z4#7$UiA?-k>Jsyli zC9VXcu+G4tSr<;4c?{vzOfar%h1h6p?X$6$r1&XpGz#q>NKTXs0SEGrCxK}Mn9xvS zRXs-nCQ-D>qKycZBAGIwOypoUDGa2AxT1L|`GOX7Fp*g#Xe^jz!PtWI96#z@jTHz| zPKWB^j5d&-Yd`%QKBkM0v}vUc4G%!Dt-=P7x|D!Tb-^UY){;{B;kG$B1y4E`G1m(2 zp)%?_7~5bVoRI*GfbO^OnaAJ+gP&vYB?kY5fiN|{ffzrS5PvK>9DWY2+F_a3YHE{` zUt-d4MF2icFvA3@ESDDXfi2Ljf)PWD6qjD3vQTA>mXPkZ3Fpjgh2_JVtzV{W&)w0uPv}A^dal<^u z25JsXQgCS~R2>OoxH`%O`H&jqHQYM%2Ozj&s97LEkN*0K(#;Sbn5j2>ZKzY?gQ2|jDvx&YokS_4tXSsddB!*_ z^4Sjgw1Rkt)IOHJhcCXL!Ot@Ic?Mr*@CyunnZa)|_$>zH$53Uc4?#A-~DL#1ksr(ChOaCio{|`S$wVwb0 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc b/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7af28d3c64f3522c927944f6c2574e5cc208e2c GIT binary patch literal 17632 zcmc(HTW}m#dfxP9t{j3S2$2*eQN6m6Bas72t6gbfMJ5Fj5-kd(MN-^_v>7y}8^8cF z-Lt2A2x2l&?4{P;jV;@WE3vDbO~}N#s9a9Pj*}{$0N}3QGE^U&K7FqL`Tzg?x1;dj!AcIlzxOnZa-Px7E$P3;k|FQrk|}?!B^!UucD_?sDj2L|wTqq7QVDt6%eTv&%2Gx01>_Gb z9gutx`RY9g+M&tarkH1|`p+I-PDerH1Z=-!3 z?Y@b2_QtG#%0KVtHeOw|Fy1dp%~Pud?}B#`^#{0JwWGmKxN6hGMw)(Nv_0|V|NPP``%Tw`I>iH{(bNdEpHJuzV36C*U z*c)%KbhYAr=-v3Nu=J*9+{o2F{t{Gb_ntzZqG4uoAlzyw$ouScTwu-Eoj z(CTI#Rwmx6>6Ek1t=m_)?kAKVh3z|jqZzg_mvnuJu~5gy{7Tphyu=RNj-M2iANN$y zBrLKY^ERG&Jkc}~&$yo(x+wWE4>J1IB1Vbr?YTHSt%(*!@uO&f~ r+M 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

DgBlV1Q znMq%I+F1YtZUzlSxZzU3dl7g9;~x2je;1M-1WH)eAoMbH9qexm09&G$dSON#I)sKK zHHTOwm^&b>W`rhDUHF8nYzU(wx7ACY&-DOxRbz|0bhuCNXgi%=YD%$#=Lku8Su9E3Sh*6Ua;n zy;K<+cemhD#m9_~ZHy2E?y#=`!BmuZlWiCdJk5Y(+Vyg~dp3X+N(6jz@{zy$6N>KlcosYOxq zk&TNQRT$sZe?%o*fUWaSesS^U0z$}jOgV($3n)zk%ol3LLe0F1XK}Ii4ZXlW$7ju8 z3vlcKtim&svRKa%Hy-J0$9a1FB1HzYRKyi^C^+$0R4CIoo_BT}dK>|#~ zvrDxa*Q@|?n3p94B{_KWTh}i)=HI(K|NfQ5cbAUnSpX0KCm9Ez9s5b~CdU8BRY_?c z3J+0N3#~`kzsRt>MlQFT|%zY0@QhG=Jp8yDiXDCBb zxQT)B@|&#i+bqe0n8QFv)Re9R9k0S@D289rzqJ%hww?yeV`_;_%9d>z+u@-=os{0v zXW852>rsNFgc}0X`2JJW#C>P;%Mwl{+pheTd3@ORA-^$BpWhg#Z%UlL`Oq#_{;zr7e#E=d ox=!WGr)Q>KHBZ`) str: + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +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) -> 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, 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, 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.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.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, + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO, bool], bool], + find_binary: t.Callable[[t.IO], 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, + 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, + 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, int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO: + """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: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO, bool]: + binary = "b" in mode + + # 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, af), True + + +class _AtomicFile: + def __init__(self, f: t.IO, 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, exc_value, tb): # type: ignore + 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) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO] = 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 get_filesystem_encoding() + + 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) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO] +) -> t.Callable[[], t.TextIO]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.TextIO: + stream = src_func() + 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/lib/python3.10/site-packages/click/_termui_impl.py b/lib/python3.10/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..4b979bc --- /dev/null +++ b/lib/python3.10/site-packages/click/_termui_impl.py @@ -0,0 +1,717 @@ +""" +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 ._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 = label or "" + if file is None: + file = _default_text_stdout() + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width = width + self.autowidth = 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 = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.start = self.last_eta = time.time() + self.eta_known = False + self.finished = False + self.max_width: t.Optional[int] = None + self.entered = False + self.current_item: t.Optional[V] = None + self.is_hidden = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar": + self.entered = True + self.render_progress() + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + 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() + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/lib/python3.10/site-packages/click/_textwrap.py b/lib/python3.10/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/lib/python3.10/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/lib/python3.10/site-packages/click/_winconsole.py b/lib/python3.10/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/lib/python3.10/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/lib/python3.10/site-packages/click/core.py b/lib/python3.10/site-packages/click/core.py new file mode 100644 index 0000000..5abfb0f --- /dev/null +++ b/lib/python3.10/site-packages/click/core.py @@ -0,0 +1,2998 @@ +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 partial +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.Dict[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.Dict[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, exc_value, tb): # type: ignore + 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) + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", t.Callable[..., t.Any]], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + """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 = other_cmd.callback + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[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.Dict[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 it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invokable 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): + echo(file=sys.stderr) + raise Abort() from None + 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.Dict[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``. + """ + if complete_var is None: + complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").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.Dict[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + text = self.help if self.help is not None else "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + text = inspect.cleandoc(text).partition("\f")[0] + 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. + """ + + 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) # type: ignore + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commmands`` 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.Dict[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.Dict[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 + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + func: t.Optional[t.Callable] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + 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] = 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. + """ + + 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 later 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, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type = 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: + 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: + convert: t.Callable[[t.Any], t.Any] = partial( + self.type, param=self, ctx=ctx + ) + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Tuple: + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Tuple: + 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. + + .. 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 + + if is_flag and default_is_missing and not self.required: + self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False + + if flag_value is None: + flag_value = not self.default + + 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 = 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'.") + + if self.multiple and self.is_flag: + raise TypeError("'multiple' is not valid with 'is_flag', use 'count'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return param.flag_value # type: ignore + + 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 parameter constructor. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/lib/python3.10/site-packages/click/decorators.py b/lib/python3.10/site-packages/click/decorators.py new file mode 100644 index 0000000..28618dc --- /dev/null +++ b/lib/python3.10/site-packages/click/decorators.py @@ -0,0 +1,497 @@ +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 + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command]) + + +def pass_context(f: F) -> F: + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def pass_obj(f: F) -> F: + """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, **kwargs): # type: ignore + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def make_pass_decorator( + object_type: t.Type, ensure: bool = False +) -> "t.Callable[[F], F]": + """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: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + + 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(t.cast(F, new_func), f) + + return decorator + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[F], F]": + """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: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, 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) + + +@t.overload +def command( + __func: t.Callable[..., t.Any], +) -> Command: + ... + + +@t.overload +def command( + name: t.Optional[str] = None, + **attrs: t.Any, +) -> t.Callable[..., Command]: + ... + + +@t.overload +def command( + name: t.Optional[str] = None, + cls: t.Type[CmdType] = ..., + **attrs: t.Any, +) -> t.Callable[..., CmdType]: + ... + + +def command( + name: t.Union[str, t.Callable[..., t.Any], None] = None, + cls: t.Optional[t.Type[Command]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[..., Command]]: + 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[..., 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 = Command + + def decorator(f: t.Callable[..., t.Any]) -> Command: + 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__ + + cmd = cls( # type: ignore[misc] + name=name or f.__name__.lower().replace("_", "-"), # type: ignore[arg-type] + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +@t.overload +def group( + __func: t.Callable[..., t.Any], +) -> Group: + ... + + +@t.overload +def group( + name: t.Optional[str] = None, + **attrs: t.Any, +) -> t.Callable[[F], Group]: + ... + + +def group( + name: t.Union[str, t.Callable[..., t.Any], None] = None, **attrs: t.Any +) -> t.Union[Group, t.Callable[[F], Group]]: + """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 attrs.get("cls") is None: + attrs["cls"] = Group + + if callable(name): + grp: t.Callable[[F], Group] = t.cast(Group, command(**attrs)) + return grp(name) + + return t.cast(Group, command(name, **attrs)) + + +def _param_memo(f: FC, 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, **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. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + """ + + def decorator(f: FC) -> FC: + ArgumentClass = attrs.pop("cls", None) or Argument + _param_memo(f, ArgumentClass(param_decls, **attrs)) + return f + + return decorator + + +def option(*param_decls: str, **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. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + """ + + def decorator(f: FC) -> FC: + # Issue 926, copy attrs, so pre-defined options can re-use the same cls= + option_attrs = attrs.copy() + OptionClass = option_attrs.pop("cls", None) or Option + _param_memo(f, OptionClass(param_decls, **option_attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + t.cast(str, message) + % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/lib/python3.10/site-packages/click/exceptions.py b/lib/python3.10/site-packages/click/exceptions.py new file mode 100644 index 0000000..9e20b3e --- /dev/null +++ b/lib/python3.10/site-packages/click/exceptions.py @@ -0,0 +1,287 @@ +import os +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo + +if t.TYPE_CHECKING: + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO] = 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 = os.fsdecode(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 = code diff --git a/lib/python3.10/site-packages/click/formatting.py b/lib/python3.10/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/lib/python3.10/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/lib/python3.10/site-packages/click/globals.py b/lib/python3.10/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/lib/python3.10/site-packages/click/globals.py @@ -0,0 +1,68 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: + ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/lib/python3.10/site-packages/click/parser.py b/lib/python3.10/site-packages/click/parser.py new file mode 100644 index 0000000..2d5a2ed --- /dev/null +++ b/lib/python3.10/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes = 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: str, 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 = 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 = 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 re-combinate 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/lib/python3.10/site-packages/click/py.typed b/lib/python3.10/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.10/site-packages/click/shell_completion.py b/lib/python3.10/site-packages/click/shell_completion.py new file mode 100644 index 0000000..c17a8e6 --- /dev/null +++ b/lib/python3.10/site-packages/click/shell_completion.py @@ -0,0 +1,580 @@ +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.Dict[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 = value + self.type = type + self.help = 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 +} + +compdef %(complete_func)s %(prog_name)s; +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response; + + for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + set response $response $value; + end; + + 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.Dict[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("-", "_"), 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 + + def _check_version(self) -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + raise RuntimeError( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ) + ) + else: + raise RuntimeError( + _("Couldn't detect Bash version, shell completion is not supported.") + ) + + 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}" + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: t.Type[ShellComplete], name: t.Optional[str] = None +) -> None: + """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 + + +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 + value = ctx.params[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.Dict[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: + 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/lib/python3.10/site-packages/click/termui.py b/lib/python3.10/site-packages/click/termui.py new file mode 100644 index 0000000..bfb2f5a --- /dev/null +++ b/lib/python3.10/site-packages/click/termui.py @@ -0,0 +1,787 @@ +import inspect +import io +import itertools +import os +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from ._compat import WIN +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 # type: ignore + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + if WIN: + os.system("cls") + else: + sys.stdout.write("\033[2J\033[1;1H") + + +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/lib/python3.10/site-packages/click/testing.py b/lib/python3.10/site-packages/click/testing.py new file mode 100644 index 0000000..e395c2e --- /dev/null +++ b/lib/python3.10/site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO, 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(t.cast(bytes, 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 = 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]] = 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] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO]] = 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]] = 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) # type: ignore[type-var] + os.chdir(dt) + + try: + yield t.cast(str, dt) + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/lib/python3.10/site-packages/click/types.py b/lib/python3.10/site-packages/click/types.py new file mode 100644 index 0000000..b45ee53 --- /dev/null +++ b/lib/python3.10/site-packages/click/types.py @@ -0,0 +1,1073 @@ +import os +import stat +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 get_filesystem_encoding +from ._compat import open_stream +from .exceptions import BadParameter +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 = 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 = get_filesystem_encoding() + 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 = 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] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter = 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.Any) -> bool: + if self.lazy is not None: + return self.lazy + if value == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + if hasattr(value, "read") or hasattr(value, "write"): + return value + + lazy = self.resolve_lazy_flag(value) + + if lazy: + f: t.IO = t.cast( + t.IO, + LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ), + ) + + if ctx is not None: + ctx.call_on_close(f.close_intelligently) # type: ignore + + return f + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"'{os.fsdecode(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")] + + +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 ``type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter = 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] = 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 = _("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, rv: t.Any) -> t.Any: + if self.type is not None and not isinstance(rv, self.type): + if self.type is str: + rv = os.fsdecode(rv) + elif self.type is bytes: + rv = os.fsencode(rv) + else: + rv = self.type(rv) + + return rv + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + 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=os.fsdecode(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=os.fsdecode(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=os.fsdecode(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=os.fsdecode(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=os.fsdecode(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=os.fsdecode(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, ParamType]]) -> None: + self.types = [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/lib/python3.10/site-packages/click/utils.py b/lib/python3.10/site-packages/click/utils.py new file mode 100644 index 0000000..8283788 --- /dev/null +++ b/lib/python3.10/site-packages/click/utils.py @@ -0,0 +1,580 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType + +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 get_filesystem_encoding +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 + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: F) -> F: + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args, **kwargs): # type: ignore + try: + return func(*args, **kwargs) + except Exception: + pass + + return update_wrapper(t.cast(F, wrapper), func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(get_filesystem_encoding()) + 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: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name = filename + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO] + + if filename == "-": + 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: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + 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) -> None: + self._file = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + 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() + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast(t.IO, 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, KeepOpenFile(f)) + + return f + + +def format_filename( + filename: t.Union[str, bytes, os.PathLike], shorten: bool = False +) -> str: + """Formats a filename for user display. The main purpose of this + function is to ensure that the filename can be displayed at all. This + will decode the filename to unicode if necessary in a way that it will + not fail. Optionally, it can shorten the filename to not include the + full path to the filename. + + :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) + + return os.fsdecode(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 affect 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) -> 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. + if getattr(_main, "__package__", None) is 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/lib/python3.10/site-packages/distutils-precedence.pth b/lib/python3.10/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..7f009fe --- /dev/null +++ b/lib/python3.10/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/lib/python3.10/site-packages/flask/__init__.py b/lib/python3.10/site-packages/flask/__init__.py new file mode 100644 index 0000000..e02531c --- /dev/null +++ b/lib/python3.10/site-packages/flask/__init__.py @@ -0,0 +1,71 @@ +from markupsafe import escape +from markupsafe import Markup + +from . import json as json +from .app import Flask as Flask +from .app import Request as Request +from .app import Response as Response +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 signals_available as signals_available +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 + +__version__ = "2.2.2" + + +def __getattr__(name): + if name == "_app_ctx_stack": + import warnings + from .globals import __app_ctx_stack + + warnings.warn( + "'_app_ctx_stack' is deprecated and will be removed in Flask 2.3.", + DeprecationWarning, + stacklevel=2, + ) + return __app_ctx_stack + + if name == "_request_ctx_stack": + import warnings + from .globals import __request_ctx_stack + + warnings.warn( + "'_request_ctx_stack' is deprecated and will be removed in Flask 2.3.", + DeprecationWarning, + stacklevel=2, + ) + return __request_ctx_stack + + raise AttributeError(name) diff --git a/lib/python3.10/site-packages/flask/__main__.py b/lib/python3.10/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/lib/python3.10/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71edae73f4d10bd01870a8f9ef60b97b942bb0cb GIT binary patch literal 2393 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 A9smFU literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/cli.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/cli.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..335fcd7a4c435657d19f38872a06743a34a67013 GIT binary patch literal 26883 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39578ba90859b37f0946bfc78960cb0ac05a707c GIT binary patch literal 12437 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef92870f21409e4476036c61ed57a8168355242b GIT binary patch literal 5935 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d998aa2eab2366b500ace7fc502694d0114419d3 GIT binary patch literal 3311 zcmcImNpIZ96=sp_Zi>BV^&(leX^$sLXFRRhg5+QXHe`<-BvFh=Ge&qJC|0ROiA{2f z)mj?LCH8fGK@ebk^f5mt%rPhbg$$CJ?-jePmMkF1AtdmCr)E2rXpLlhpFB@g+#FjHOq{ z((C*hq*osp{JOu4m6x%@3f?PvhZ}l_Rk4B{ZeX<)v8;DkMgE^k6N!!45Sn!Lr^_;y88OIp=Bkazg(D;uDda-M#j`{9CL!N2L&Oz=Ea4_MJ`1YD#5)l z<=#=8B;Jnjq!?s}kj1H|gUtJ^_j%6)F5X&y%~P3Is7wlvhbp}9Wzt(4-J^xIDvTlo zm#6lG7Y(Hpsq&&K6nk&UOK%XK+JHnHill3o&QU1SIPDjuO`P^fx$t;w8KU$>rHA_n zIeCo;xvC-y;L2J+QbB$3lvAp|0RDTj%#DWrwndDnJmR zDg=X!4-?{BLGaBmOvW0kP*Rc~OQuTeQFH9{fH=k~bL^$&93pF#Y2E1i7nwXj^m^G)6)_iHw(Es?p2Wy1to<(b zU3YsA38zkSXp-c_8;CHaGzpb=k`293DKW??5s_X)WZLd9jVkM6byAH>h2Vm_)2TJJ zRnOZ-VrI#q!05QR?;$F^VUEPU%pmtDR(quA;R(hW`qOUD+Y&S%$(=>R0kXF`#xAma zKsg_$U*8?|*EtX4p1HGoms2%^IPYnB#Bm-(~9bSE38JQ$!XpfZ*Xy&;CvKSkLb z7YRLu^(9rh(LXK$RaQ;x{{bi=1grtvv+eEYsD8R#_B=GqVwk8);DBQlIx6`caJW;T zcp*-!yuIv*92p*FF+571N7U^kV$d7SSD=k|p}Hw4_sS*#HP#l1 zyZ&#x=9m}1W2?Y@Pf(G9w@-Y$mJE^82Y6F_KPU4>v`IN{fL_Q<(A(1sAbmGfuZ|OX! q>in;$;}p+8Tm${dtfNDm-5tyJmKrV)wOQu})2hFtwtcz$dhJK48Bmx2 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21fa3025dfeace0ff871e345e8ffd36f8fb150d8 GIT binary patch literal 24021 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2d265c03b5aeaf48f01e4dbd25612309a64bc9b GIT binary patch literal 2461 zcmZuz&u<$=6rNeHf5uLlkX9{4XbM!VrC=9TaIm5XktS_LR4O&4!l?32c4qB$*1PV^ zxT&L1fm#Xp1Gpd#$+1Un{44C0Q~v-CaDcuyyG~QWN;}?}eecbC-+b>|Cyhpp!1epD zOa7k~LjJ(X$*TyHPvO?Tz#xdA5$R^Xv`g*W=@#JEiQG}KTcku3gd3GcPk0w$Z zcr0#4T<@kOCCx;|K02Me9GI-bt(RdiM3oI0Qb8|}d&D@y0&L{)pCIaH7z<_wl8q8= z7$1*SGFBlsl1Zf!#k5h9k5~YYXaxpQ=yMY$af{s!7-xA#H3nCx8TU>2Sgx=r=`)is z&)d`euw`Ru&s$*$L{WR8mTUsI=jo|#X(PbE^IA0<1;S2~3GTNyai&=Bt>hD&3Wa{j~_n3PDZoLV^0XZZ`^|@{M!rJ!S2XL4q#1NP83X_qyke1jEF-r1barf8*0R-?W@Bcv zg(hqH;hjPNtG|v2ybZ&5Q2WCQ)-ohNkX`yEq2!Sxpe>v9&I@R3yIs>soz}IqoL8jg z!81GPIe1E|t9=>ECu6nt9>zt8oo~;R{SO9Q_iTV(?%7(6P(<`v>)2&`vsp|RPoGItoucE&CIN^DH5on$2qQ)b3cYJ_kd^b*bx|r!Fly z4t3qqKki>{Rb7Br`=5M$`6}0d^+-1LLw5P9EghC&PkT0_a^0<6#jrv4mo5$_GF@eG%3wriv>ED8-cj z25i15vDGEBdW!-GB+1x>2EW`E3(EMngMuWP#)VuUI@}o5 z@gR6B6PKPfU(E!=?%cu^KIMn=6qEkhnaY6j5zJ6wl8x{o-diz3>rrRCf)tpeS*Y~Q9X;+PgK zPHF)Nl2)L?E$ra5XzRDMOly$ztxQnT1t9}IiOj64pc9bVwjEyUud-dx@Zp1LWG_SG zW27PKW4%##>a^n2pbymhu+TiKE@BM$w*um6rei2DrKUT-C)Mu0ob=&40iCN*L(_6U zN_L=)voAqo`>VSfz4cog>!07gb2Cc?8zC)i!*}NP7r7wM3f@VQD66UQ2HFb6BdtUA zn-(@BRa!lMv`L;Q&VFWWg_YH;A=gmq^}8@sNQG7?6zG(oNT;wwm+Q5&F08r#o-e)v DW?#VM literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/scaffold.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/scaffold.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4f78de41158e6929d03feec2a3a13de27e62f1b GIT binary patch literal 24711 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 =)HuYPm#joJChZyB2;F((n= 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c3d810b28a47edb7ed891019f26800ddb3490a4 GIT binary patch literal 13613 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7eb8f97ab22411bdcaeae0959bd41cd3a7a19621 GIT binary patch literal 2400 zcmZuy&2A$_5bpW$*csbNoc%{DG=c*JZDJ5tgcbpd_L4;ew9p({6L&kAWHRIJZg1As zo=6@9j(g+Fz)s(|w%rJiad1vx%kFnoqu|6PU z4>8RzAd*QhXWU!H;QZV_4|w1)8SwBaEAE9%br$bmoz+XA=cxNUIT zjvIj+Ic^8sj`R-M?v3B!13TFDs*Qv6T$x!qQC~lrkZ^r;v3Q7S-UCr^S2FI)p7d29 z0~MZjRB#Ut%FZ;Bk?dY|c;w7)Xded-s<43ZDv;%*inOwGT~vMXC_Ph$*>REPlK@)H zAfD!@n1(W8*-P)Gf9W5xR~}xfBgkF_RcKT`)ugFIk}yrme?A?5W0W@IT$RQ6GiABmFj0fFR_6o1-0~ z*o$TVD&!mgyEl+S?8Pb$8Si5bFoytM49Jmen~%PaCGxeq<&u@|c#J)sCP#TzoGG1T zCYcxM^EAuTqg*{mCR(LdC22ARB9aMmW0H%^o+S1}B?fVflhw!ytMn8Y#a3#QG|$Tm zlNeRVtT;}}X|l>!ax}Lvk>@a(<+ZW2Xw4|COP!QOk`@349aXte`$_V+Fjl3KEXk7O ztpb$kng>Z{TQly0)48z;P*Q4o6ui*K^K(^LgR>G=lA^4y$ZFgB?eT+u!K*vS*lSfl zD05Y?4F)y91bgX&qWTV54K?4{sJcR+wuI2soBo3y0%KNWR)|~JbP$R>fcNHF0q!>{ zRfzYSDmuHM{|WNe4yrU-Kf!cX+E=&>Uj=#tJDM)hw}}v9YeFEVdM)HVaIShnRL}YY zX!Et}C;;xdx(!J060ZN?@A?PJCx@;wfvDre%xAMwBMaAXl^m%_IyZGz8t9?qb*dMn zio7J06M#s`eRROVSM$PV=jwAphrZLk-udBN=m>(-ee!{XzK7r6e&GML9IgA}wCeoq z=potJB(g>11`*1q9ue6gaucKqJ}DOZE-l}nWp`2*1$q_luNd(>OZi~6P*T{E-?i!- zj;A`y7vkDZEHl#>7@ed>Xf;vUbM!?qEj1rrTdpOlb=B1^z1q+Vdo1+cjP8f`gY78v zdR|mF;pK=PkfV0@G}5QElFQpi3O6)@y+&cVrPZ^!GIkFE*A|M~jbI9JniEKFHWHMe zMqc-1c~LBH9hVm7>%;2BM7eIcypzsm@X)Fk7MHB)kJdJ3b7%OPsGQAk*A~8Y27P{y zz67{@_eK@j#SFK)yzuS{Fs{+^(WA(;`HFJCC^*Fi)?92v8ymhBo9p^(fe>|U_%)G>4R2y2 tRd)H8)Dq0Q4kW%m@Oqe`x9RVM{vXlXaVJKrS^sT%{{WBuc5wgz literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57ee4dd39e13a3a8c7ba83dae1aaf2c099831fc9 GIT binary patch literal 6964 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..343874e4f8d23fe4c3763d7bfceb83de088340c1 GIT binary patch literal 9409 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2277a426ff68ac4fabb1c04d3b5fc20884eff3ef GIT binary patch literal 5398 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 QwF`SevfzC?TRXr1U*LMkZ~y=R literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc b/lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1eabe56766a9c9d4a0cd594518aebd7ad67cc554 GIT binary patch literal 5086 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/flask/app.py b/lib/python3.10/site-packages/flask/app.py new file mode 100644 index 0000000..db442c9 --- /dev/null +++ b/lib/python3.10/site-packages/flask/app.py @@ -0,0 +1,2548 @@ +import functools +import inspect +import json +import logging +import os +import sys +import typing as t +import weakref +from collections.abc import Iterator as _abc_Iterator +from datetime import timedelta +from itertools import chain +from threading import Lock +from types import TracebackType + +import click +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import Aborter +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.routing import BuildError +from werkzeug.routing import Map +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.urls import url_quote +from werkzeug.utils import redirect as _wz_redirect +from werkzeug.wrappers import Response as BaseResponse + +from . import cli +from . import typing as ft +from .config import Config +from .config import ConfigAttribute +from .ctx import _AppCtxGlobals +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _cv_app +from .globals import _cv_request +from .globals import g +from .globals import request +from .globals import request_ctx +from .globals import session +from .helpers import _split_blueprint_path +from .helpers import get_debug_flag +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import locked_cached_property +from .json.provider import DefaultJSONProvider +from .json.provider import JSONProvider +from .logging import create_logger +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import find_package +from .scaffold import Scaffold +from .scaffold import setupmethod +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 DispatchingJinjaLoader +from .templating import Environment +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: # pragma: no cover + import typing_extensions as te + from .blueprints import Blueprint + from .testing import FlaskClient + from .testing import FlaskCliRunner + +T_before_first_request = t.TypeVar( + "T_before_first_request", bound=ft.BeforeFirstRequestCallable +) +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) + +if sys.version_info >= (3, 8): + iscoroutinefunction = inspect.iscoroutinefunction +else: + + def iscoroutinefunction(func: t.Any) -> bool: + while inspect.ismethod(func): + func = func.__func__ + + while isinstance(func, functools.partial): + func = func.func + + return inspect.iscoroutinefunction(func) + + +def _make_timedelta(value: t.Union[timedelta, int, None]) -> t.Optional[timedelta]: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(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 that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class = Response + + #: 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("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("SECRET_KEY") + + @property + def session_cookie_name(self) -> str: + """The name of the cookie set by the session interface. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Use ``app.config["SESSION_COOKIE_NAME"]`` + instead. + """ + import warnings + + warnings.warn( + "'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use" + " 'SESSION_COOKIE_NAME' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.config["SESSION_COOKIE_NAME"] + + @session_cookie_name.setter + def session_cookie_name(self, value: str) -> None: + import warnings + + warnings.warn( + "'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use" + " 'SESSION_COOKIE_NAME' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + self.config["SESSION_COOKIE_NAME"] = value + + #: 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( + "PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta + ) + + @property + def send_file_max_age_default(self) -> t.Optional[timedelta]: + """The default value for ``max_age`` for :func:`~flask.send_file`. The default + is ``None``, which tells the browser to use conditional requests instead of a + timed cache. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Use + ``app.config["SEND_FILE_MAX_AGE_DEFAULT"]`` instead. + + .. versionchanged:: 2.0 + Defaults to ``None`` instead of 12 hours. + """ + import warnings + + warnings.warn( + "'send_file_max_age_default' is deprecated and will be removed in Flask" + " 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + return _make_timedelta(self.config["SEND_FILE_MAX_AGE_DEFAULT"]) + + @send_file_max_age_default.setter + def send_file_max_age_default(self, value: t.Union[int, timedelta, None]) -> None: + import warnings + + warnings.warn( + "'send_file_max_age_default' is deprecated and will be removed in Flask" + " 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + self.config["SEND_FILE_MAX_AGE_DEFAULT"] = _make_timedelta(value) + + @property + def use_x_sendfile(self) -> bool: + """Enable this to use the ``X-Sendfile`` feature, assuming the server supports + it, from :func:`~flask.send_file`. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Use ``app.config["USE_X_SENDFILE"]`` instead. + """ + import warnings + + warnings.warn( + "'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use" + " 'USE_X_SENDFILE' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.config["USE_X_SENDFILE"] + + @use_x_sendfile.setter + def use_x_sendfile(self, value: bool) -> None: + import warnings + + warnings.warn( + "'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use" + " 'USE_X_SENDFILE' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + self.config["USE_X_SENDFILE"] = value + + _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None + _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None + + @property # type: ignore[override] + def json_encoder(self) -> t.Type[json.JSONEncoder]: # type: ignore[override] + """The JSON encoder class to use. Defaults to + :class:`~flask.json.JSONEncoder`. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Customize + :attr:`json_provider_class` instead. + + .. versionadded:: 0.10 + """ + import warnings + + warnings.warn( + "'app.json_encoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + + if self._json_encoder is None: + from . import json + + return json.JSONEncoder + + return self._json_encoder + + @json_encoder.setter + def json_encoder(self, value: t.Type[json.JSONEncoder]) -> None: + import warnings + + warnings.warn( + "'app.json_encoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + self._json_encoder = value + + @property # type: ignore[override] + def json_decoder(self) -> t.Type[json.JSONDecoder]: # type: ignore[override] + """The JSON decoder class to use. Defaults to + :class:`~flask.json.JSONDecoder`. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Customize + :attr:`json_provider_class` instead. + + .. versionadded:: 0.10 + """ + import warnings + + warnings.warn( + "'app.json_decoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + + if self._json_decoder is None: + from . import json + + return json.JSONDecoder + + return self._json_decoder + + @json_decoder.setter + def json_decoder(self, value: t.Type[json.JSONDecoder]) -> None: + import warnings + + warnings.warn( + "'app.json_decoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + self._json_decoder = value + + json_provider_class: t.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 = {} + + #: Default configuration parameters. + default_config = ImmutableDict( + { + "ENV": None, + "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", + "JSON_AS_ASCII": None, + "JSON_SORT_KEYS": None, + "JSONIFY_PRETTYPRINT_REGULAR": None, + "JSONIFY_MIMETYPE": None, + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + } + ) + + #: 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: t.Optional[t.Type["FlaskClient"]] = 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: t.Optional[t.Type["FlaskCliRunner"]] = None + + #: 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: t.Optional[str] = None, + static_folder: t.Optional[t.Union[str, os.PathLike]] = "static", + static_host: t.Optional[str] = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: t.Optional[str] = "templates", + instance_path: t.Optional[str] = None, + instance_relative_config: bool = False, + root_path: t.Optional[str] = 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: t.List[ + t.Callable[[Exception, str, t.Dict[str, t.Any]], str] + ] = [] + + #: A list of functions that will be called at the beginning of the + #: first request to this instance. To register a function, use the + #: :meth:`before_first_request` decorator. + #: + #: .. deprecated:: 2.2 + #: Will be removed in Flask 2.3. Run setup code when + #: creating the application instead. + #: + #: .. versionadded:: 0.8 + self.before_first_request_funcs: t.List[ft.BeforeFirstRequestCallable] = [] + + #: 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: t.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: t.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: t.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 = {} + + #: 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() + + self.url_map.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 + self._before_request_lock = Lock() + + # 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 + ) + + # 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." + ) + + @locked_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 = 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 + + @property + def propagate_exceptions(self) -> bool: + """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration + value in case it's set, otherwise a sensible default is returned. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. + + .. versionadded:: 0.7 + """ + import warnings + + warnings.warn( + "'propagate_exceptions' is deprecated and will be removed in Flask 2.3.", + DeprecationWarning, + stacklevel=2, + ) + rv = self.config["PROPAGATE_EXCEPTIONS"] + if rv is not None: + return rv + return self.testing or self.debug + + @locked_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) + + @locked_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() + + @property + def got_first_request(self) -> bool: + """This attribute is set to ``True`` if the application started + handling the first request. + + .. versionadded:: 0.8 + """ + return self._got_first_request + + 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["ENV"] = os.environ.get("FLASK_ENV") or "production" + 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 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) + + @property + def templates_auto_reload(self) -> bool: + """Reload templates when they are changed. Used by + :meth:`create_jinja_environment`. It is enabled by default in debug mode. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Use ``app.config["TEMPLATES_AUTO_RELOAD"]`` + instead. + + .. versionadded:: 1.0 + This property was added but the underlying config and behavior + already existed. + """ + import warnings + + warnings.warn( + "'templates_auto_reload' is deprecated and will be removed in Flask 2.3." + " Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + rv = self.config["TEMPLATES_AUTO_RELOAD"] + return rv if rv is not None else self.debug + + @templates_auto_reload.setter + def templates_auto_reload(self, value: bool) -> None: + import warnings + + warnings.warn( + "'templates_auto_reload' is deprecated and will be removed in Flask 2.3." + " Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.", + DeprecationWarning, + stacklevel=2, + ) + self.config["TEMPLATES_AUTO_RELOAD"] = value + + 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_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`. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml")) + + def update_template_context(self, context: dict) -> 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[t.Optional[str]] = (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(func()) + + context.update(orig_ctx) + + def make_shell_context(self) -> dict: + """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 + + @property + def env(self) -> str: + """What environment the app is running in. This maps to the :data:`ENV` config + key. + + **Do not enable development when deploying in production.** + + Default: ``'production'`` + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. + """ + import warnings + + warnings.warn( + "'app.env' is deprecated and will be removed in Flask 2.3." + " Use 'app.debug' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.config["ENV"] + + @env.setter + def env(self, value: str) -> None: + import warnings + + warnings.warn( + "'app.env' is deprecated and will be removed in Flask 2.3." + " Use 'app.debug' instead.", + DeprecationWarning, + stacklevel=2, + ) + self.config["ENV"] = value + + @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"] + + @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 + + def run( + self, + host: t.Optional[str] = None, + port: t.Optional[int] = None, + debug: t.Optional[bool] = 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, let env vars override previous values + if "FLASK_ENV" in os.environ: + print( + "'FLASK_ENV' is deprecated and will not be used in" + " Flask 2.3. Use 'FLASK_DEBUG' instead.", + file=sys.stderr, + ) + self.config["ENV"] = os.environ.get("FLASK_ENV") or "production" + self.debug = get_debug_flag() + elif "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 # type: ignore + 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 # type: ignore + + return cls(self, **kwargs) # type: ignore + + @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: t.Optional[str] = None, + view_func: t.Optional[ft.RouteCallable] = None, + provide_automatic_options: t.Optional[bool] = 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 = self.url_rule_class(rule, methods=methods, **options) + rule.provide_automatic_options = provide_automatic_options # type: ignore + + self.url_map.add(rule) + 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: t.Optional[str] = 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: t.Optional[str] = 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: t.Optional[str] = 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: t.Optional[str] = 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: t.Optional[str] = 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: t.Optional[str] = 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 before_first_request(self, f: T_before_first_request) -> T_before_first_request: + """Registers a function to be run before the first request to this + instance of the application. + + The function will be called without any arguments and its return + value is ignored. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Run setup code when creating + the application instead. + + .. versionadded:: 0.8 + """ + import warnings + + warnings.warn( + "'before_first_request' is deprecated and will be removed" + " in Flask 2.3. Run setup code while creating the" + " application instead.", + DeprecationWarning, + stacklevel=2, + ) + self.before_first_request_funcs.append(f) + return 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) -> t.Optional[ft.ErrorHandlerCallable]: + """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 = (*request.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 handle_http_exception( + self, e: HTTPException + ) -> t.Union[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) + if handler is None: + return e + return self.ensure_sync(handler)(e) + + 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 handle_user_exception( + self, e: Exception + ) -> t.Union[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) + + if handler is None: + raise + + return self.ensure_sync(handler)(e) + + 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 :attr:`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, 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: t.Union[InternalServerError, ft.ResponseReturnValue] + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error) + + 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: t.Union[ + t.Tuple[type, BaseException, TracebackType], t.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 raise_routing_exception(self, request: Request) -> "te.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 + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + 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: t.Dict[str, t.Any] = req.view_args # type: ignore[assignment] + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) + + 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 + """ + # Run before_first_request functions if this is the thread's first request. + # Inlined to avoid a method call on subsequent requests. + # This is deprecated, will be removed in Flask 2.3. + if not self._got_first_request: + with self._before_request_lock: + if not self._got_first_request: + for func in self.before_first_request_funcs: + self.ensure_sync(func)() + + self._got_first_request = True + + try: + request_started.send(self) + 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: t.Union[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, 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 should_ignore_error(self, error: t.Optional[BaseException]) -> 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 ensure_sync(self, func: t.Callable) -> t.Callable: + """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.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: t.Optional[str] = None, + _method: t.Optional[str] = None, + _scheme: t.Optional[str] = None, + _external: t.Optional[bool] = 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: + rv = f"{rv}#{url_quote(_anchor)}" + + return rv + + 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) + + 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, _abc_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, request.environ # type: ignore[arg-type] + ) + 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 create_url_adapter( + self, request: t.Optional[Request] + ) -> t.Optional[MapAdapter]: + """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 inject_url_defaults(self, endpoint: str, values: dict) -> 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[t.Optional[str]] = (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: t.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 + + def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]: + """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 + + 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: t.Optional[BaseException] = _sentinel # type: ignore + ) -> 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, exc=exc) + + def do_teardown_appcontext( + self, exc: t.Optional[BaseException] = _sentinel # type: ignore + ) -> 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, 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: dict) -> 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 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: dict, start_response: t.Callable) -> t.Any: + """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: t.Optional[BaseException] = 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: dict, start_response: t.Callable) -> t.Any: + """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/lib/python3.10/site-packages/flask/blueprints.py b/lib/python3.10/site-packages/flask/blueprints.py new file mode 100644 index 0000000..104f8ac --- /dev/null +++ b/lib/python3.10/site-packages/flask/blueprints.py @@ -0,0 +1,706 @@ +import json +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 Flask + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_first_request = t.TypeVar( + "T_before_first_request", bound=ft.BeforeFirstRequestCallable +) +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: "Flask", + 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: t.Optional[str] = None, + view_func: t.Optional[t.Callable] = 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 + + _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None + _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None + + @property # type: ignore[override] + def json_encoder( # type: ignore[override] + self, + ) -> t.Union[t.Type[json.JSONEncoder], None]: + """Blueprint-local JSON encoder class to use. Set to ``None`` to use the app's. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Customize + :attr:`json_provider_class` instead. + + .. versionadded:: 0.10 + """ + import warnings + + warnings.warn( + "'bp.json_encoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self._json_encoder + + @json_encoder.setter + def json_encoder(self, value: t.Union[t.Type[json.JSONEncoder], None]) -> None: + import warnings + + warnings.warn( + "'bp.json_encoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + self._json_encoder = value + + @property # type: ignore[override] + def json_decoder( # type: ignore[override] + self, + ) -> t.Union[t.Type[json.JSONDecoder], None]: + """Blueprint-local JSON decoder class to use. Set to ``None`` to use the app's. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Customize + :attr:`json_provider_class` instead. + + .. versionadded:: 0.10 + """ + import warnings + + warnings.warn( + "'bp.json_decoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self._json_decoder + + @json_decoder.setter + def json_decoder(self, value: t.Union[t.Type[json.JSONDecoder], None]) -> None: + import warnings + + warnings.warn( + "'bp.json_decoder' is deprecated and will be removed in Flask 2.3." + " Customize 'app.json_provider_class' or 'app.json' instead.", + DeprecationWarning, + stacklevel=2, + ) + self._json_decoder = value + + def __init__( + self, + name: str, + import_name: str, + static_folder: t.Optional[t.Union[str, os.PathLike]] = None, + static_url_path: t.Optional[str] = None, + template_folder: t.Optional[str] = None, + url_prefix: t.Optional[str] = None, + subdomain: t.Optional[str] = None, + url_defaults: t.Optional[dict] = None, + root_path: t.Optional[str] = None, + cli_group: t.Optional[str] = _sentinel, # type: ignore + ): + 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 "." 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: t.List[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: t.List[t.Tuple["Blueprint", dict]] = [] + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_registered_once: + import warnings + + warnings.warn( + f"The setup method '{f_name}' can no longer be called on" + f" the blueprint '{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.\n" + "This warning will become an exception in Flask 2.3.", + UserWarning, + stacklevel=3, + ) + + @setupmethod + def record(self, func: t.Callable) -> 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: t.Callable) -> 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: "Flask", options: dict, 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: "Flask", options: dict) -> 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.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``. + + .. versionchanged:: 2.0.1 + Registering the same blueprint with the same name multiple + times is deprecated and will become an error in Flask 2.1. + """ + 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, + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + + def extend(bp_dict, parent_dict): + 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) + + 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") + + 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) + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: t.Optional[str] = None, + view_func: t.Optional[ft.RouteCallable] = None, + provide_automatic_options: t.Optional[bool] = None, + **options: t.Any, + ) -> None: + """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for + the :func:`url_for` function is prefixed with the name of the blueprint. + """ + 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: t.Optional[str] = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """Register a custom template filter, available application wide. Like + :meth:`Flask.template_filter` but for a blueprint. + + :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: t.Optional[str] = None + ) -> None: + """Register a custom template filter, available application wide. Like + :meth:`Flask.add_template_filter` but for a blueprint. Works exactly + like the :meth:`app_template_filter` decorator. + + :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: t.Optional[str] = None + ) -> t.Callable[[T_template_test], T_template_test]: + """Register a custom template test, available application wide. Like + :meth:`Flask.template_test` but for a blueprint. + + .. 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: t.Optional[str] = None + ) -> None: + """Register a custom template test, available application wide. Like + :meth:`Flask.add_template_test` but for a blueprint. Works exactly + like the :meth:`app_template_test` decorator. + + .. 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: t.Optional[str] = None + ) -> t.Callable[[T_template_global], T_template_global]: + """Register a custom template global, available application wide. Like + :meth:`Flask.template_global` but for a blueprint. + + .. 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: t.Optional[str] = None + ) -> None: + """Register a custom template global, available application wide. Like + :meth:`Flask.add_template_global` but for a blueprint. Works exactly + like the :meth:`app_template_global` decorator. + + .. 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:`Flask.before_request`. Such a function is executed + before each request, even if outside of a blueprint. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def before_app_first_request( + self, f: T_before_first_request + ) -> T_before_first_request: + """Like :meth:`Flask.before_first_request`. Such a function is + executed before the first request to the application. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Run setup code when creating + the application instead. + """ + import warnings + + warnings.warn( + "'before_app_first_request' is deprecated and will be" + " removed in Flask 2.3. Use 'record_once' instead to run" + " setup code when registering the blueprint.", + DeprecationWarning, + stacklevel=2, + ) + self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) + return f + + @setupmethod + def after_app_request(self, f: T_after_request) -> T_after_request: + """Like :meth:`Flask.after_request` but for a blueprint. Such a function + is executed after each request, even if outside of the blueprint. + """ + 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:`Flask.teardown_request` but for a blueprint. Such a + function is executed when tearing down each request, even if outside of + the blueprint. + """ + 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:`Flask.context_processor` but for a blueprint. Such a + function is executed each request, even if outside of the blueprint. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_errorhandler( + self, code: t.Union[t.Type[Exception], int] + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Like :meth:`Flask.errorhandler` but for a blueprint. This + handler is used for all requests, even if outside of the blueprint. + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.record_once(lambda s: s.app.errorhandler(code)(f)) + return f + + return decorator + + @setupmethod + def app_url_value_preprocessor( + self, f: T_url_value_preprocessor + ) -> T_url_value_preprocessor: + """Same as :meth:`url_value_preprocessor` but application wide.""" + 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: + """Same as :meth:`url_defaults` but application wide.""" + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/lib/python3.10/site-packages/flask/cli.py b/lib/python3.10/site-packages/flask/cli.py new file mode 100644 index 0000000..82fe819 --- /dev/null +++ b/lib/python3.10/site-packages/flask/cli.py @@ -0,0 +1,1051 @@ +from __future__ import annotations + +import ast +import inspect +import os +import platform +import re +import sys +import traceback +import typing as t +from functools import update_wrapper +from operator import attrgetter + +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: + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module): + """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): + """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, app_name): + """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} + 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): + """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]) + + +def locate_app(module_name, app_name, raise_if_not_found=True): + 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: + 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 + + 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, param, value): + if not value or ctx.resilient_parsing: + return + + import werkzeug + from . import __version__ + + click.echo( + f"Python {platform.python_version()}\n" + f"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: t.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 = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, 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: + break + + if not app: + 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) + + +def with_appcontext(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, *args, **kwargs): + 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) + + +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(self, *args, **kwargs): + """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): + if wrap_for_ctx: + f = with_appcontext(f) + return click.Group.command(self, *args, **kwargs)(f) + + return decorator + + def group(self, *args, **kwargs): + """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 click.Group.group(self, *args, **kwargs) + + +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): + 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, name): + 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: + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + def list_commands(self, ctx): + 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, other): + """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 | 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, app_import_path): + """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): + self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) + + def convert(self, value, param, ctx): + 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, param, value): + """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, param, ctx): + items = self.split_envvar_value(value) + 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, + host, + port, + reload, + debugger, + with_threads, + cert, + extra_files, + exclude_patterns, +): + """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 = 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, start_response): + 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, + ) + + +@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 = {} + + # 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", "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")) + + if sort in ("endpoint", "rule"): + rules = sorted(rules, key=attrgetter(sort)) + elif sort == "methods": + rules = sorted(rules, key=lambda rule: sorted(rule.methods)) # type: ignore + + rule_methods = [ + ", ".join(sorted(rule.methods - ignored_methods)) # type: ignore + for rule in rules + ] + + headers = ("Endpoint", "Methods", "Rule") + widths = ( + max(len(rule.endpoint) for rule in rules), + max(len(methods) for methods in rule_methods), + max(len(rule.rule) for rule in rules), + ) + widths = [max(len(h), w) for h, w in zip(headers, widths)] + row = "{{0:<{0}}} {{1:<{1}}} {{2:<{2}}}".format(*widths) + + click.echo(row.format(*headers).strip()) + click.echo(row.format(*("-" * width for width in widths))) + + for rule, methods in zip(rules, rule_methods): + click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip()) + + +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/lib/python3.10/site-packages/flask/config.py b/lib/python3.10/site-packages/flask/config.py new file mode 100644 index 0000000..7b6a137 --- /dev/null +++ b/lib/python3.10/site-packages/flask/config.py @@ -0,0 +1,337 @@ +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + + +class ConfigAttribute: + """Makes an attribute forward to the config""" + + def __init__(self, name: str, get_converter: t.Optional[t.Callable] = None) -> None: + self.__name__ = name + self.get_converter = get_converter + + def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any: + 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 + + def __set__(self, obj: t.Any, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): + """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, defaults: t.Optional[dict] = 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, 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: t.Union[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, + load: t.Callable[[t.IO[t.Any]], t.Mapping], + silent: bool = False, + ) -> 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 toml + app.config.from_file("config.toml", load=toml.load) + + :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. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename) 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.Optional[t.Mapping[str, t.Any]] = 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: t.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 + ) -> t.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/lib/python3.10/site-packages/flask/ctx.py b/lib/python3.10/site-packages/flask/ctx.py new file mode 100644 index 0000000..ca28449 --- /dev/null +++ b/lib/python3.10/site-packages/flask/ctx.py @@ -0,0 +1,438 @@ +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 .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.Optional[t.Any] = 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) -> ft.AfterRequestCallable: + """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 + + +def copy_current_request_context(f: t.Callable) -> t.Callable: + """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, **kwargs): + with ctx: + return ctx.app.ensure_sync(f)(*args, **kwargs) + + return update_wrapper(wrapper, f) + + +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: t.List[contextvars.Token] = [] + + 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) + + def pop(self, exc: t.Optional[BaseException] = _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) + + def __enter__(self) -> "AppContext": + self.push() + return self + + def __exit__( + self, + exc_type: t.Optional[type], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> 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: dict, + request: t.Optional["Request"] = None, + session: t.Optional["SessionMixin"] = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + request.json_module = app.json # type: ignore[misc] + 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: t.Optional[t.List[t.Tuple[str, str]]] = None + self.session: t.Optional["SessionMixin"] = 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: t.List[ft.AfterRequestCallable] = [] + + self._cv_tokens: t.List[t.Tuple[contextvars.Token, t.Optional[AppContext]]] = [] + + 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: t.Optional[BaseException] = _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: t.Optional[type], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> 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/lib/python3.10/site-packages/flask/debughelpers.py b/lib/python3.10/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..b063989 --- /dev/null +++ b/lib/python3.10/site-packages/flask/debughelpers.py @@ -0,0 +1,158 @@ +import typing as t + +from .app import Flask +from .blueprints import Blueprint +from .globals import request_ctx + + +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, key): + 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): + 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): + exc = request.routing_exception + 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): + """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): + def __getitem__(self, key): + 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) -> t.Generator: + 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: Flask, template, attempts) -> 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, Flask): + 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/lib/python3.10/site-packages/flask/globals.py b/lib/python3.10/site-packages/flask/globals.py new file mode 100644 index 0000000..b230ef7 --- /dev/null +++ b/lib/python3.10/site-packages/flask/globals.py @@ -0,0 +1,107 @@ +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 + + +class _FakeStack: + def __init__(self, name: str, cv: ContextVar[t.Any]) -> None: + self.name = name + self.cv = cv + + def _warn(self): + import warnings + + warnings.warn( + f"'_{self.name}_ctx_stack' is deprecated and will be" + " removed in Flask 2.3. Use 'g' to store data, or" + f" '{self.name}_ctx' to access the current context.", + DeprecationWarning, + stacklevel=3, + ) + + def push(self, obj: t.Any) -> None: + self._warn() + self.cv.set(obj) + + def pop(self) -> t.Any: + self._warn() + ctx = self.cv.get(None) + self.cv.set(None) + return ctx + + @property + def top(self) -> t.Optional[t.Any]: + self._warn() + return self.cv.get(None) + + +_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_stack = _FakeStack("app", _cv_app) +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_stack = _FakeStack("request", _cv_request) +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 +) + + +def __getattr__(name: str) -> t.Any: + if name == "_app_ctx_stack": + import warnings + + warnings.warn( + "'_app_ctx_stack' is deprecated and will be remoevd in Flask 2.3.", + DeprecationWarning, + stacklevel=2, + ) + return __app_ctx_stack + + if name == "_request_ctx_stack": + import warnings + + warnings.warn( + "'_request_ctx_stack' is deprecated and will be remoevd in Flask 2.3.", + DeprecationWarning, + stacklevel=2, + ) + return __request_ctx_stack + + raise AttributeError(name) diff --git a/lib/python3.10/site-packages/flask/helpers.py b/lib/python3.10/site-packages/flask/helpers.py new file mode 100644 index 0000000..15990d0 --- /dev/null +++ b/lib/python3.10/site-packages/flask/helpers.py @@ -0,0 +1,705 @@ +import os +import pkgutil +import socket +import sys +import typing as t +from datetime import datetime +from functools import lru_cache +from functools import update_wrapper +from threading import RLock + +import werkzeug.utils +from werkzeug.exceptions import abort as _wz_abort +from werkzeug.utils import redirect as _wz_redirect + +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 werkzeug.wrappers import Response as BaseResponse + from .wrappers import Response + import typing_extensions as te + + +def get_env() -> str: + """Get the environment the app is running in, indicated by the + :envvar:`FLASK_ENV` environment variable. The default is + ``'production'``. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. + """ + import warnings + + warnings.warn( + "'FLASK_ENV' and 'get_env' are deprecated and will be removed" + " in Flask 2.3. Use 'FLASK_DEBUG' instead.", + DeprecationWarning, + stacklevel=2, + ) + return os.environ.get("FLASK_ENV") or "production" + + +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") + + if not val: + env = os.environ.get("FLASK_ENV") + + if env is not None: + print( + "'FLASK_ENV' is deprecated and will not be used in" + " Flask 2.3. Use 'FLASK_DEBUG' instead.", + file=sys.stderr, + ) + return env == "development" + + return False + + return 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.Union[ + 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 + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore + + def generator() -> t.Generator: + 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() # type: ignore + + # 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 + + +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) # type: ignore + + +def url_for( + endpoint: str, + *, + _anchor: t.Optional[str] = None, + _method: t.Optional[str] = None, + _scheme: t.Optional[str] = None, + _external: t.Optional[bool] = 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: t.Optional[t.Type["BaseResponse"]] = 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( # type: ignore[misc] + code: t.Union[int, "BaseResponse"], *args: t.Any, **kwargs: t.Any +) -> "te.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 + message_flashed.send( + current_app._get_current_object(), # type: ignore + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> t.Union[t.List[str], t.List[t.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) -> t.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: t.Union[os.PathLike, str, t.BinaryIO], + mimetype: t.Optional[str] = None, + as_attachment: bool = False, + download_name: t.Optional[str] = None, + conditional: bool = True, + etag: t.Union[bool, str] = True, + last_modified: t.Optional[t.Union[datetime, int, float]] = None, + max_age: t.Optional[ + t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] + ] = 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 + deprecated 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: t.Union[os.PathLike, str], + path: t.Union[os.PathLike, 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. + loader = pkgutil.get_loader(import_name) + + # 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 or import_name == "__main__": + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) # type: ignore + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +class locked_cached_property(werkzeug.utils.cached_property): + """A :func:`property` that is only evaluated once. Like + :class:`werkzeug.utils.cached_property` except access uses a lock + for thread safety. + + .. versionchanged:: 2.0 + Inherits from Werkzeug's ``cached_property`` (and ``property``). + """ + + def __init__( + self, + fget: t.Callable[[t.Any], t.Any], + name: t.Optional[str] = None, + doc: t.Optional[str] = None, + ) -> None: + super().__init__(fget, name=name, doc=doc) + self.lock = RLock() + + def __get__(self, obj: object, type: type = None) -> t.Any: # type: ignore + if obj is None: + return self + + with self.lock: + return super().__get__(obj, type=type) + + def __set__(self, obj: object, value: t.Any) -> None: + with self.lock: + super().__set__(obj, value) + + def __delete__(self, obj: object) -> None: + with self.lock: + super().__delete__(obj) + + +def is_ip(value: str) -> bool: + """Determine if the given string is an IP address. + + :param value: value to check + :type value: str + + :return: True if string is an IP address + :rtype: bool + """ + for family in (socket.AF_INET, socket.AF_INET6): + try: + socket.inet_pton(family, value) + except OSError: + pass + else: + return True + + return False + + +@lru_cache(maxsize=None) +def _split_blueprint_path(name: str) -> t.List[str]: + out: t.List[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/lib/python3.10/site-packages/flask/json/__init__.py b/lib/python3.10/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..65d8829 --- /dev/null +++ b/lib/python3.10/site-packages/flask/json/__init__.py @@ -0,0 +1,342 @@ +from __future__ import annotations + +import json as _json +import typing as t + +from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps + +from ..globals import current_app +from .provider import _default + +if t.TYPE_CHECKING: # pragma: no cover + from ..app import Flask + from ..wrappers import Response + + +class JSONEncoder(_json.JSONEncoder): + """The default JSON encoder. Handles extra types compared to the + built-in :class:`json.JSONEncoder`. + + - :class:`datetime.datetime` and :class:`datetime.date` are + serialized to :rfc:`822` strings. This is the same as the HTTP + date format. + - :class:`decimal.Decimal` is serialized to a string. + - :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. + + Assign a subclass of this to :attr:`flask.Flask.json_encoder` or + :attr:`flask.Blueprint.json_encoder` to override the default. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Use ``app.json`` instead. + """ + + def __init__(self, **kwargs) -> None: + import warnings + + warnings.warn( + "'JSONEncoder' is deprecated and will be removed in" + " Flask 2.3. Use 'Flask.json' to provide an alternate" + " JSON implementation instead.", + DeprecationWarning, + stacklevel=3, + ) + super().__init__(**kwargs) + + def default(self, o: t.Any) -> t.Any: + """Convert ``o`` to a JSON serializable type. See + :meth:`json.JSONEncoder.default`. Python does not support + overriding how basic types like ``str`` or ``list`` are + serialized, they are handled before this method. + """ + return _default(o) + + +class JSONDecoder(_json.JSONDecoder): + """The default JSON decoder. + + This does not change any behavior from the built-in + :class:`json.JSONDecoder`. + + Assign a subclass of this to :attr:`flask.Flask.json_decoder` or + :attr:`flask.Blueprint.json_decoder` to override the default. + + .. deprecated:: 2.2 + Will be removed in Flask 2.3. Use ``app.json`` instead. + """ + + def __init__(self, **kwargs) -> None: + import warnings + + warnings.warn( + "'JSONDecoder' is deprecated and will be removed in" + " Flask 2.3. Use 'Flask.json' to provide an alternate" + " JSON implementation instead.", + DeprecationWarning, + stacklevel=3, + ) + super().__init__(**kwargs) + + +def dumps(obj: t.Any, *, app: Flask | None = None, **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.2 + Calls ``current_app.json.dumps``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. 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 app is not None: + import warnings + + warnings.warn( + "The 'app' parameter is deprecated and will be removed in" + " Flask 2.3. Call 'app.json.dumps' directly instead.", + DeprecationWarning, + stacklevel=2, + ) + else: + app = current_app + + if app: + return app.json.dumps(obj, **kwargs) + + kwargs.setdefault("default", _default) + return _json.dumps(obj, **kwargs) + + +def dump( + obj: t.Any, fp: t.IO[str], *, app: Flask | None = None, **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.2 + Calls ``current_app.json.dump``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, will be + removed in Flask 2.1. + """ + if app is not None: + import warnings + + warnings.warn( + "The 'app' parameter is deprecated and will be removed in" + " Flask 2.3. Call 'app.json.dump' directly instead.", + DeprecationWarning, + stacklevel=2, + ) + else: + app = current_app + + if app: + app.json.dump(obj, fp, **kwargs) + else: + kwargs.setdefault("default", _default) + _json.dump(obj, fp, **kwargs) + + +def loads(s: str | bytes, *, app: Flask | None = None, **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.2 + Calls ``current_app.json.loads``, 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 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 app is not None: + import warnings + + warnings.warn( + "The 'app' parameter is deprecated and will be removed in" + " Flask 2.3. Call 'app.json.loads' directly instead.", + DeprecationWarning, + stacklevel=2, + ) + else: + app = current_app + + if app: + return app.json.loads(s, **kwargs) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[t.AnyStr], *, app: Flask | None = None, **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.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 app is not None: + import warnings + + warnings.warn( + "The 'app' parameter is deprecated and will be removed in" + " Flask 2.3. Call 'app.json.load' directly instead.", + DeprecationWarning, + stacklevel=2, + ) + else: + app = current_app + + if app: + return app.json.load(fp, **kwargs) + + return _json.load(fp, **kwargs) + + +def htmlsafe_dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize an object to a string of JSON with :func:`dumps`, then + replace HTML-unsafe characters with Unicode escapes and mark the + result safe with :class:`~markupsafe.Markup`. + + This is available in templates as the ``|tojson`` filter. + + The returned string is safe to render in HTML documents and + `` + + + +

+ +
+
+

Console Locked

+

+ The console is locked and needs to be unlocked by entering the PIN. + You can find the PIN printed out on the standard output of your + shell that runs the server. +

+

PIN: + + +

+
+
+ + +""" + +PAGE_HTML = ( + HEADER + + """\ +

%(exception_type)s

+
+

%(exception)s

+
+

Traceback (most recent call last)

+%(summary)s +
+

+ This is the Copy/Paste friendly version of the traceback. +

+ +
+
+ The debugger caught an exception in your WSGI application. You can now + look at the traceback which led to the error. + If you enable JavaScript you can also use additional features such as code + execution (if the evalex feature is enabled), automatic pasting of the + exceptions and much more. +
+""" + + FOOTER + + """ + +""" +) + +CONSOLE_HTML = ( + HEADER + + """\ +

Interactive Console

+
+In this console you can execute Python expressions in the context of the +application. The initial namespace was created by the debugger automatically. +
+
The Console requires JavaScript.
+""" + + FOOTER +) + +SUMMARY_HTML = """\ +
+ %(title)s +
    %(frames)s
+ %(description)s +
+""" + +FRAME_HTML = """\ +
+

File "%(filename)s", + line %(lineno)s, + in %(function_name)s

+
%(lines)s
+
+""" + + +def _process_traceback( + exc: BaseException, + te: t.Optional[traceback.TracebackException] = None, + *, + skip: int = 0, + hide: bool = True, +) -> traceback.TracebackException: + if te is None: + te = traceback.TracebackException.from_exception(exc, lookup_lines=False) + + # Get the frames the same way StackSummary.extract did, in order + # to match each frame with the FrameSummary to augment. + frame_gen = traceback.walk_tb(exc.__traceback__) + limit = getattr(sys, "tracebacklimit", None) + + if limit is not None: + if limit < 0: + limit = 0 + + frame_gen = itertools.islice(frame_gen, limit) + + if skip: + frame_gen = itertools.islice(frame_gen, skip, None) + del te.stack[:skip] + + new_stack: t.List[DebugFrameSummary] = [] + hidden = False + + # Match each frame with the FrameSummary that was generated. + # Hide frames using Paste's __traceback_hide__ rules. Replace + # all visible FrameSummary with DebugFrameSummary. + for (f, _), fs in zip(frame_gen, te.stack): + if hide: + hide_value = f.f_locals.get("__traceback_hide__", False) + + if hide_value in {"before", "before_and_this"}: + new_stack = [] + hidden = False + + if hide_value == "before_and_this": + continue + elif hide_value in {"reset", "reset_and_this"}: + hidden = False + + if hide_value == "reset_and_this": + continue + elif hide_value in {"after", "after_and_this"}: + hidden = True + + if hide_value == "after_and_this": + continue + elif hide_value or hidden: + continue + + frame_args: t.Dict[str, t.Any] = { + "filename": fs.filename, + "lineno": fs.lineno, + "name": fs.name, + "locals": f.f_locals, + "globals": f.f_globals, + } + + if hasattr(fs, "colno"): + frame_args["colno"] = fs.colno # type: ignore[attr-defined] + frame_args["end_colno"] = fs.end_colno # type: ignore[attr-defined] + + new_stack.append(DebugFrameSummary(**frame_args)) + + # The codeop module is used to compile code from the interactive + # debugger. Hide any codeop frames from the bottom of the traceback. + while new_stack: + module = new_stack[0].global_ns.get("__name__") + + if module is None: + module = new_stack[0].local_ns.get("__name__") + + if module == "codeop": + del new_stack[0] + else: + break + + te.stack[:] = new_stack + + if te.__context__: + context_exc = t.cast(BaseException, exc.__context__) + te.__context__ = _process_traceback(context_exc, te.__context__, hide=hide) + + if te.__cause__: + cause_exc = t.cast(BaseException, exc.__cause__) + te.__cause__ = _process_traceback(cause_exc, te.__cause__, hide=hide) + + return te + + +class DebugTraceback: + __slots__ = ("_te", "_cache_all_tracebacks", "_cache_all_frames") + + def __init__( + self, + exc: BaseException, + te: t.Optional[traceback.TracebackException] = None, + *, + skip: int = 0, + hide: bool = True, + ) -> None: + self._te = _process_traceback(exc, te, skip=skip, hide=hide) + + def __str__(self) -> str: + return f"<{type(self).__name__} {self._te}>" + + @cached_property + def all_tracebacks( + self, + ) -> t.List[t.Tuple[t.Optional[str], traceback.TracebackException]]: + out = [] + current = self._te + + while current is not None: + if current.__cause__ is not None: + chained_msg = ( + "The above exception was the direct cause of the" + " following exception" + ) + chained_exc = current.__cause__ + elif current.__context__ is not None and not current.__suppress_context__: + chained_msg = ( + "During handling of the above exception, another" + " exception occurred" + ) + chained_exc = current.__context__ + else: + chained_msg = None + chained_exc = None + + out.append((chained_msg, current)) + current = chained_exc + + return out + + @cached_property + def all_frames(self) -> t.List["DebugFrameSummary"]: + return [ + f for _, te in self.all_tracebacks for f in te.stack # type: ignore[misc] + ] + + def render_traceback_text(self) -> str: + return "".join(self._te.format()) + + def render_traceback_html(self, include_title: bool = True) -> str: + library_frames = [f.is_library for f in self.all_frames] + mark_library = 0 < sum(library_frames) < len(library_frames) + rows = [] + + if not library_frames: + classes = "traceback noframe-traceback" + else: + classes = "traceback" + + for msg, current in reversed(self.all_tracebacks): + row_parts = [] + + if msg is not None: + row_parts.append(f'
  • {msg}:
    ') + + for frame in current.stack: + frame = t.cast(DebugFrameSummary, frame) + info = f' title="{escape(frame.info)}"' if frame.info else "" + row_parts.append(f"{frame.render_html(mark_library)}") + + rows.append("\n".join(row_parts)) + + is_syntax_error = issubclass(self._te.exc_type, SyntaxError) + + if include_title: + if is_syntax_error: + title = "Syntax Error" + else: + title = "Traceback (most recent call last):" + else: + title = "" + + exc_full = escape("".join(self._te.format_exception_only())) + + if is_syntax_error: + description = f"
    {exc_full}
    " + else: + description = f"
    {exc_full}
    " + + return SUMMARY_HTML % { + "classes": classes, + "title": f"

    {title}

    ", + "frames": "\n".join(rows), + "description": description, + } + + def render_debugger_html( + self, evalex: bool, secret: str, evalex_trusted: bool + ) -> str: + exc_lines = list(self._te.format_exception_only()) + plaintext = "".join(self._te.format()) + return PAGE_HTML % { + "evalex": "true" if evalex else "false", + "evalex_trusted": "true" if evalex_trusted else "false", + "console": "false", + "title": exc_lines[0], + "exception": escape("".join(exc_lines)), + "exception_type": escape(self._te.exc_type.__name__), + "summary": self.render_traceback_html(include_title=False), + "plaintext": escape(plaintext), + "plaintext_cs": re.sub("-{2,}", "-", plaintext), + "secret": secret, + } + + +class DebugFrameSummary(traceback.FrameSummary): + """A :class:`traceback.FrameSummary` that can evaluate code in the + frame's namespace. + """ + + __slots__ = ( + "local_ns", + "global_ns", + "_cache_info", + "_cache_is_library", + "_cache_console", + ) + + def __init__( + self, + *, + locals: t.Dict[str, t.Any], + globals: t.Dict[str, t.Any], + **kwargs: t.Any, + ) -> None: + super().__init__(locals=None, **kwargs) + self.local_ns = locals + self.global_ns = globals + + @cached_property + def info(self) -> t.Optional[str]: + return self.local_ns.get("__traceback_info__") + + @cached_property + def is_library(self) -> bool: + return any( + self.filename.startswith((path, os.path.realpath(path))) + for path in sysconfig.get_paths().values() + ) + + @cached_property + def console(self) -> Console: + return Console(self.global_ns, self.local_ns) + + def eval(self, code: str) -> t.Any: + return self.console.eval(code) + + def render_html(self, mark_library: bool) -> str: + context = 5 + lines = linecache.getlines(self.filename) + line_idx = self.lineno - 1 # type: ignore[operator] + start_idx = max(0, line_idx - context) + stop_idx = min(len(lines), line_idx + context + 1) + rendered_lines = [] + + def render_line(line: str, cls: str) -> None: + line = line.expandtabs().rstrip() + stripped_line = line.strip() + prefix = len(line) - len(stripped_line) + colno = getattr(self, "colno", 0) + end_colno = getattr(self, "end_colno", 0) + + if cls == "current" and colno and end_colno: + arrow = ( + f'\n{" " * prefix}' + f'{" " * (colno - prefix)}{"^" * (end_colno - colno)}' + ) + else: + arrow = "" + + rendered_lines.append( + f'
    {" " * prefix}'
    +                f"{escape(stripped_line) if stripped_line else ' '}"
    +                f"{arrow if arrow else ''}
    " + ) + + if lines: + for line in lines[start_idx:line_idx]: + render_line(line, "before") + + render_line(lines[line_idx], "current") + + for line in lines[line_idx + 1 : stop_idx]: + render_line(line, "after") + + return FRAME_HTML % { + "id": id(self), + "filename": escape(self.filename), + "lineno": self.lineno, + "function_name": escape(self.name), + "lines": "\n".join(rendered_lines), + "library": "library" if mark_library and self.is_library else "", + } + + +def render_console_html(secret: str, evalex_trusted: bool) -> str: + return CONSOLE_HTML % { + "evalex": "true", + "evalex_trusted": "true" if evalex_trusted else "false", + "console": "true", + "title": "Console", + "secret": secret, + } diff --git a/lib/python3.10/site-packages/werkzeug/exceptions.py b/lib/python3.10/site-packages/werkzeug/exceptions.py new file mode 100644 index 0000000..013df72 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/exceptions.py @@ -0,0 +1,884 @@ +"""Implements a number of Python exceptions which can be raised from within +a view to trigger a standard HTTP non-200 response. + +Usage Example +------------- + +.. code-block:: python + + from werkzeug.wrappers.request import Request + from werkzeug.exceptions import HTTPException, NotFound + + def view(request): + raise NotFound() + + @Request.application + def application(request): + try: + return view(request) + except HTTPException as e: + return e + +As you can see from this example those exceptions are callable WSGI +applications. However, they are not Werkzeug response objects. You +can get a response object by calling ``get_response()`` on a HTTP +exception. + +Keep in mind that you may have to pass an environ (WSGI) or scope +(ASGI) to ``get_response()`` because some errors fetch additional +information relating to the request. + +If you want to hook in a different exception page to say, a 404 status +code, you can add a second except for a specific subclass of an error: + +.. code-block:: python + + @Request.application + def application(request): + try: + return view(request) + except NotFound as e: + return not_found(request) + except HTTPException as e: + return e + +""" +import typing as t +from datetime import datetime + +from markupsafe import escape +from markupsafe import Markup + +from ._internal import _get_environ + +if t.TYPE_CHECKING: + import typing_extensions as te + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIEnvironment + from .datastructures import WWWAuthenticate + from .sansio.response import Response + from .wrappers.request import Request as WSGIRequest # noqa: F401 + from .wrappers.response import Response as WSGIResponse # noqa: F401 + + +class HTTPException(Exception): + """The base class for all HTTP exceptions. This exception can be called as a WSGI + application to render a default error page or you can catch the subclasses + of it independently and render nicer error messages. + + .. versionchanged:: 2.1 + Removed the ``wrap`` class method. + """ + + code: t.Optional[int] = None + description: t.Optional[str] = None + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + super().__init__() + if description is not None: + self.description = description + self.response = response + + @property + def name(self) -> str: + """The status name.""" + from .http import HTTP_STATUS_CODES + + return HTTP_STATUS_CODES.get(self.code, "Unknown Error") # type: ignore + + def get_description( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> str: + """Get the description.""" + if self.description is None: + description = "" + elif not isinstance(self.description, str): + description = str(self.description) + else: + description = self.description + + description = escape(description).replace("\n", Markup("
    ")) + return f"

    {description}

    " + + def get_body( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> str: + """Get the HTML body.""" + return ( + "\n" + "\n" + f"{self.code} {escape(self.name)}\n" + f"

    {escape(self.name)}

    \n" + f"{self.get_description(environ)}\n" + ) + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + """Get a list of headers.""" + return [("Content-Type", "text/html; charset=utf-8")] + + def get_response( + self, + environ: t.Optional[t.Union["WSGIEnvironment", "WSGIRequest"]] = None, + scope: t.Optional[dict] = None, + ) -> "Response": + """Get a response object. If one was passed to the exception + it's returned directly. + + :param environ: the optional environ for the request. This + can be used to modify the response depending + on how the request looked like. + :return: a :class:`Response` object or a subclass thereof. + """ + from .wrappers.response import Response as WSGIResponse # noqa: F811 + + if self.response is not None: + return self.response + if environ is not None: + environ = _get_environ(environ) + headers = self.get_headers(environ, scope) + return WSGIResponse(self.get_body(environ, scope), self.code, headers) + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + """Call the exception as WSGI application. + + :param environ: the WSGI environment. + :param start_response: the response callable provided by the WSGI + server. + """ + response = t.cast("WSGIResponse", self.get_response(environ)) + return response(environ, start_response) + + def __str__(self) -> str: + code = self.code if self.code is not None else "???" + return f"{code} {self.name}: {self.description}" + + def __repr__(self) -> str: + code = self.code if self.code is not None else "???" + return f"<{type(self).__name__} '{code}: {self.name}'>" + + +class BadRequest(HTTPException): + """*400* `Bad Request` + + Raise if the browser sends something to the application the application + or server cannot handle. + """ + + code = 400 + description = ( + "The browser (or proxy) sent a request that this server could " + "not understand." + ) + + +class BadRequestKeyError(BadRequest, KeyError): + """An exception that is used to signal both a :exc:`KeyError` and a + :exc:`BadRequest`. Used by many of the datastructures. + """ + + _description = BadRequest.description + #: Show the KeyError along with the HTTP error message in the + #: response. This should be disabled in production, but can be + #: useful in a debug mode. + show_exception = False + + def __init__(self, arg: t.Optional[str] = None, *args: t.Any, **kwargs: t.Any): + super().__init__(*args, **kwargs) + + if arg is None: + KeyError.__init__(self) + else: + KeyError.__init__(self, arg) + + @property # type: ignore + def description(self) -> str: # type: ignore + if self.show_exception: + return ( + f"{self._description}\n" + f"{KeyError.__name__}: {KeyError.__str__(self)}" + ) + + return self._description + + @description.setter + def description(self, value: str) -> None: + self._description = value + + +class ClientDisconnected(BadRequest): + """Internal exception that is raised if Werkzeug detects a disconnected + client. Since the client is already gone at that point attempting to + send the error message to the client might not work and might ultimately + result in another exception in the server. Mainly this is here so that + it is silenced by default as far as Werkzeug is concerned. + + Since disconnections cannot be reliably detected and are unspecified + by WSGI to a large extent this might or might not be raised if a client + is gone. + + .. versionadded:: 0.8 + """ + + +class SecurityError(BadRequest): + """Raised if something triggers a security error. This is otherwise + exactly like a bad request error. + + .. versionadded:: 0.9 + """ + + +class BadHost(BadRequest): + """Raised if the submitted host is badly formatted. + + .. versionadded:: 0.11.2 + """ + + +class Unauthorized(HTTPException): + """*401* ``Unauthorized`` + + Raise if the user is not authorized to access a resource. + + The ``www_authenticate`` argument should be used to set the + ``WWW-Authenticate`` header. This is used for HTTP basic auth and + other schemes. Use :class:`~werkzeug.datastructures.WWWAuthenticate` + to create correctly formatted values. Strictly speaking a 401 + response is invalid if it doesn't provide at least one value for + this header, although real clients typically don't care. + + :param description: Override the default message used for the body + of the response. + :param www-authenticate: A single value, or list of values, for the + WWW-Authenticate header(s). + + .. versionchanged:: 2.0 + Serialize multiple ``www_authenticate`` items into multiple + ``WWW-Authenticate`` headers, rather than joining them + into a single value, for better interoperability. + + .. versionchanged:: 0.15.3 + If the ``www_authenticate`` argument is not set, the + ``WWW-Authenticate`` header is not set. + + .. versionchanged:: 0.15.3 + The ``response`` argument was restored. + + .. versionchanged:: 0.15.1 + ``description`` was moved back as the first argument, restoring + its previous position. + + .. versionchanged:: 0.15.0 + ``www_authenticate`` was added as the first argument, ahead of + ``description``. + """ + + code = 401 + description = ( + "The server could not verify that you are authorized to access" + " the URL requested. You either supplied the wrong credentials" + " (e.g. a bad password), or your browser doesn't understand" + " how to supply the credentials required." + ) + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + www_authenticate: t.Optional[ + t.Union["WWWAuthenticate", t.Iterable["WWWAuthenticate"]] + ] = None, + ) -> None: + super().__init__(description, response) + + from .datastructures import WWWAuthenticate + + if isinstance(www_authenticate, WWWAuthenticate): + www_authenticate = (www_authenticate,) + + self.www_authenticate = www_authenticate + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.www_authenticate: + headers.extend(("WWW-Authenticate", str(x)) for x in self.www_authenticate) + return headers + + +class Forbidden(HTTPException): + """*403* `Forbidden` + + Raise if the user doesn't have the permission for the requested resource + but was authenticated. + """ + + code = 403 + description = ( + "You don't have the permission to access the requested" + " resource. It is either read-protected or not readable by the" + " server." + ) + + +class NotFound(HTTPException): + """*404* `Not Found` + + Raise if a resource does not exist and never existed. + """ + + code = 404 + description = ( + "The requested URL was not found on the server. If you entered" + " the URL manually please check your spelling and try again." + ) + + +class MethodNotAllowed(HTTPException): + """*405* `Method Not Allowed` + + Raise if the server used a method the resource does not handle. For + example `POST` if the resource is view only. Especially useful for REST. + + The first argument for this exception should be a list of allowed methods. + Strictly speaking the response would be invalid if you don't provide valid + methods in the header which you can do with that list. + """ + + code = 405 + description = "The method is not allowed for the requested URL." + + def __init__( + self, + valid_methods: t.Optional[t.Iterable[str]] = None, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + """Takes an optional list of valid http methods + starting with werkzeug 0.3 the list will be mandatory.""" + super().__init__(description=description, response=response) + self.valid_methods = valid_methods + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.valid_methods: + headers.append(("Allow", ", ".join(self.valid_methods))) + return headers + + +class NotAcceptable(HTTPException): + """*406* `Not Acceptable` + + Raise if the server can't return any content conforming to the + `Accept` headers of the client. + """ + + code = 406 + description = ( + "The resource identified by the request is only capable of" + " generating response entities which have content" + " characteristics not acceptable according to the accept" + " headers sent in the request." + ) + + +class RequestTimeout(HTTPException): + """*408* `Request Timeout` + + Raise to signalize a timeout. + """ + + code = 408 + description = ( + "The server closed the network connection because the browser" + " didn't finish the request within the specified time." + ) + + +class Conflict(HTTPException): + """*409* `Conflict` + + Raise to signal that a request cannot be completed because it conflicts + with the current state on the server. + + .. versionadded:: 0.7 + """ + + code = 409 + description = ( + "A conflict happened while processing the request. The" + " resource might have been modified while the request was being" + " processed." + ) + + +class Gone(HTTPException): + """*410* `Gone` + + Raise if a resource existed previously and went away without new location. + """ + + code = 410 + description = ( + "The requested URL is no longer available on this server and" + " there is no forwarding address. If you followed a link from a" + " foreign page, please contact the author of this page." + ) + + +class LengthRequired(HTTPException): + """*411* `Length Required` + + Raise if the browser submitted data but no ``Content-Length`` header which + is required for the kind of processing the server does. + """ + + code = 411 + description = ( + "A request with this method requires a valid Content-" + "Length header." + ) + + +class PreconditionFailed(HTTPException): + """*412* `Precondition Failed` + + Status code used in combination with ``If-Match``, ``If-None-Match``, or + ``If-Unmodified-Since``. + """ + + code = 412 + description = ( + "The precondition on the request for the URL failed positive evaluation." + ) + + +class RequestEntityTooLarge(HTTPException): + """*413* `Request Entity Too Large` + + The status code one should return if the data submitted exceeded a given + limit. + """ + + code = 413 + description = "The data value transmitted exceeds the capacity limit." + + +class RequestURITooLarge(HTTPException): + """*414* `Request URI Too Large` + + Like *413* but for too long URLs. + """ + + code = 414 + description = ( + "The length of the requested URL exceeds the capacity limit for" + " this server. The request cannot be processed." + ) + + +class UnsupportedMediaType(HTTPException): + """*415* `Unsupported Media Type` + + The status code returned if the server is unable to handle the media type + the client transmitted. + """ + + code = 415 + description = ( + "The server does not support the media type transmitted in the request." + ) + + +class RequestedRangeNotSatisfiable(HTTPException): + """*416* `Requested Range Not Satisfiable` + + The client asked for an invalid part of the file. + + .. versionadded:: 0.7 + """ + + code = 416 + description = "The server cannot provide the requested range." + + def __init__( + self, + length: t.Optional[int] = None, + units: str = "bytes", + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + """Takes an optional `Content-Range` header value based on ``length`` + parameter. + """ + super().__init__(description=description, response=response) + self.length = length + self.units = units + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.length is not None: + headers.append(("Content-Range", f"{self.units} */{self.length}")) + return headers + + +class ExpectationFailed(HTTPException): + """*417* `Expectation Failed` + + The server cannot meet the requirements of the Expect request-header. + + .. versionadded:: 0.7 + """ + + code = 417 + description = "The server could not meet the requirements of the Expect header" + + +class ImATeapot(HTTPException): + """*418* `I'm a teapot` + + The server should return this if it is a teapot and someone attempted + to brew coffee with it. + + .. versionadded:: 0.7 + """ + + code = 418 + description = "This server is a teapot, not a coffee machine" + + +class UnprocessableEntity(HTTPException): + """*422* `Unprocessable Entity` + + Used if the request is well formed, but the instructions are otherwise + incorrect. + """ + + code = 422 + description = ( + "The request was well-formed but was unable to be followed due" + " to semantic errors." + ) + + +class Locked(HTTPException): + """*423* `Locked` + + Used if the resource that is being accessed is locked. + """ + + code = 423 + description = "The resource that is being accessed is locked." + + +class FailedDependency(HTTPException): + """*424* `Failed Dependency` + + Used if the method could not be performed on the resource + because the requested action depended on another action and that action failed. + """ + + code = 424 + description = ( + "The method could not be performed on the resource because the" + " requested action depended on another action and that action" + " failed." + ) + + +class PreconditionRequired(HTTPException): + """*428* `Precondition Required` + + The server requires this request to be conditional, typically to prevent + the lost update problem, which is a race condition between two or more + clients attempting to update a resource through PUT or DELETE. By requiring + each client to include a conditional header ("If-Match" or "If-Unmodified- + Since") with the proper value retained from a recent GET request, the + server ensures that each client has at least seen the previous revision of + the resource. + """ + + code = 428 + description = ( + "This request is required to be conditional; try using" + ' "If-Match" or "If-Unmodified-Since".' + ) + + +class _RetryAfter(HTTPException): + """Adds an optional ``retry_after`` parameter which will set the + ``Retry-After`` header. May be an :class:`int` number of seconds or + a :class:`~datetime.datetime`. + """ + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + retry_after: t.Optional[t.Union[datetime, int]] = None, + ) -> None: + super().__init__(description, response) + self.retry_after = retry_after + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + + if self.retry_after: + if isinstance(self.retry_after, datetime): + from .http import http_date + + value = http_date(self.retry_after) + else: + value = str(self.retry_after) + + headers.append(("Retry-After", value)) + + return headers + + +class TooManyRequests(_RetryAfter): + """*429* `Too Many Requests` + + The server is limiting the rate at which this user receives + responses, and this request exceeds that rate. (The server may use + any convenient method to identify users and their request rates). + The server may include a "Retry-After" header to indicate how long + the user should wait before retrying. + + :param retry_after: If given, set the ``Retry-After`` header to this + value. May be an :class:`int` number of seconds or a + :class:`~datetime.datetime`. + + .. versionchanged:: 1.0 + Added ``retry_after`` parameter. + """ + + code = 429 + description = "This user has exceeded an allotted request count. Try again later." + + +class RequestHeaderFieldsTooLarge(HTTPException): + """*431* `Request Header Fields Too Large` + + The server refuses to process the request because the header fields are too + large. One or more individual fields may be too large, or the set of all + headers is too large. + """ + + code = 431 + description = "One or more header fields exceeds the maximum size." + + +class UnavailableForLegalReasons(HTTPException): + """*451* `Unavailable For Legal Reasons` + + This status code indicates that the server is denying access to the + resource as a consequence of a legal demand. + """ + + code = 451 + description = "Unavailable for legal reasons." + + +class InternalServerError(HTTPException): + """*500* `Internal Server Error` + + Raise if an internal server error occurred. This is a good fallback if an + unknown error occurred in the dispatcher. + + .. versionchanged:: 1.0.0 + Added the :attr:`original_exception` attribute. + """ + + code = 500 + description = ( + "The server encountered an internal error and was unable to" + " complete your request. Either the server is overloaded or" + " there is an error in the application." + ) + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + original_exception: t.Optional[BaseException] = None, + ) -> None: + #: The original exception that caused this 500 error. Can be + #: used by frameworks to provide context when handling + #: unexpected errors. + self.original_exception = original_exception + super().__init__(description=description, response=response) + + +class NotImplemented(HTTPException): + """*501* `Not Implemented` + + Raise if the application does not support the action requested by the + browser. + """ + + code = 501 + description = "The server does not support the action requested by the browser." + + +class BadGateway(HTTPException): + """*502* `Bad Gateway` + + If you do proxying in your application you should return this status code + if you received an invalid response from the upstream server it accessed + in attempting to fulfill the request. + """ + + code = 502 + description = ( + "The proxy server received an invalid response from an upstream server." + ) + + +class ServiceUnavailable(_RetryAfter): + """*503* `Service Unavailable` + + Status code you should return if a service is temporarily + unavailable. + + :param retry_after: If given, set the ``Retry-After`` header to this + value. May be an :class:`int` number of seconds or a + :class:`~datetime.datetime`. + + .. versionchanged:: 1.0 + Added ``retry_after`` parameter. + """ + + code = 503 + description = ( + "The server is temporarily unable to service your request due" + " to maintenance downtime or capacity problems. Please try" + " again later." + ) + + +class GatewayTimeout(HTTPException): + """*504* `Gateway Timeout` + + Status code you should return if a connection to an upstream server + times out. + """ + + code = 504 + description = "The connection to an upstream server timed out." + + +class HTTPVersionNotSupported(HTTPException): + """*505* `HTTP Version Not Supported` + + The server does not support the HTTP protocol version used in the request. + """ + + code = 505 + description = ( + "The server does not support the HTTP protocol version used in the request." + ) + + +default_exceptions: t.Dict[int, t.Type[HTTPException]] = {} + + +def _find_exceptions() -> None: + for obj in globals().values(): + try: + is_http_exception = issubclass(obj, HTTPException) + except TypeError: + is_http_exception = False + if not is_http_exception or obj.code is None: + continue + old_obj = default_exceptions.get(obj.code, None) + if old_obj is not None and issubclass(obj, old_obj): + continue + default_exceptions[obj.code] = obj + + +_find_exceptions() +del _find_exceptions + + +class Aborter: + """When passed a dict of code -> exception items it can be used as + callable that raises exceptions. If the first argument to the + callable is an integer it will be looked up in the mapping, if it's + a WSGI application it will be raised in a proxy exception. + + The rest of the arguments are forwarded to the exception constructor. + """ + + def __init__( + self, + mapping: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, + extra: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, + ) -> None: + if mapping is None: + mapping = default_exceptions + self.mapping = dict(mapping) + if extra is not None: + self.mapping.update(extra) + + def __call__( + self, code: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any + ) -> "te.NoReturn": + from .sansio.response import Response + + if isinstance(code, Response): + raise HTTPException(response=code) + + if code not in self.mapping: + raise LookupError(f"no exception for {code!r}") + + raise self.mapping[code](*args, **kwargs) + + +def abort( + status: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any +) -> "te.NoReturn": + """Raises an :py:exc:`HTTPException` for the given status code or WSGI + application. + + If a status code is given, it will be looked up in the list of + exceptions and will raise that exception. If passed a WSGI application, + it will wrap it in a proxy WSGI exception and raise that:: + + abort(404) # 404 Not Found + abort(Response('Hello World')) + + """ + _aborter(status, *args, **kwargs) + + +_aborter: Aborter = Aborter() diff --git a/lib/python3.10/site-packages/werkzeug/formparser.py b/lib/python3.10/site-packages/werkzeug/formparser.py new file mode 100644 index 0000000..10d58ca --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/formparser.py @@ -0,0 +1,455 @@ +import typing as t +from functools import update_wrapper +from io import BytesIO +from itertools import chain +from typing import Union + +from . import exceptions +from .datastructures import FileStorage +from .datastructures import Headers +from .datastructures import MultiDict +from .http import parse_options_header +from .sansio.multipart import Data +from .sansio.multipart import Epilogue +from .sansio.multipart import Field +from .sansio.multipart import File +from .sansio.multipart import MultipartDecoder +from .sansio.multipart import NeedData +from .urls import url_decode_stream +from .wsgi import _make_chunk_iter +from .wsgi import get_content_length +from .wsgi import get_input_stream + +# there are some platforms where SpooledTemporaryFile is not available. +# In that case we need to provide a fallback. +try: + from tempfile import SpooledTemporaryFile +except ImportError: + from tempfile import TemporaryFile + + SpooledTemporaryFile = None # type: ignore + +if t.TYPE_CHECKING: + import typing as te + from _typeshed.wsgi import WSGIEnvironment + + t_parse_result = t.Tuple[t.IO[bytes], MultiDict, MultiDict] + + class TStreamFactory(te.Protocol): + def __call__( + self, + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str], + content_length: t.Optional[int] = None, + ) -> t.IO[bytes]: + ... + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _exhaust(stream: t.IO[bytes]) -> None: + bts = stream.read(64 * 1024) + while bts: + bts = stream.read(64 * 1024) + + +def default_stream_factory( + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str], + content_length: t.Optional[int] = None, +) -> t.IO[bytes]: + max_size = 1024 * 500 + + if SpooledTemporaryFile is not None: + return t.cast(t.IO[bytes], SpooledTemporaryFile(max_size=max_size, mode="rb+")) + elif total_content_length is None or total_content_length > max_size: + return t.cast(t.IO[bytes], TemporaryFile("rb+")) + + return BytesIO() + + +def parse_form_data( + environ: "WSGIEnvironment", + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + max_content_length: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + silent: bool = True, +) -> "t_parse_result": + """Parse the form data in the environ and return it as tuple in the form + ``(stream, form, files)``. You should only call this method if the + transport method is `POST`, `PUT`, or `PATCH`. + + If the mimetype of the data transmitted is `multipart/form-data` the + files multidict will be filled with `FileStorage` objects. If the + mimetype is unknown the input stream is wrapped and returned as first + argument, else the stream is empty. + + This is a shortcut for the common usage of :class:`FormDataParser`. + + Have a look at :doc:`/request_data` for more details. + + .. versionadded:: 0.5 + The `max_form_memory_size`, `max_content_length` and + `cls` parameters were added. + + .. versionadded:: 0.5.1 + The optional `silent` flag was added. + + :param environ: the WSGI environment to be used for parsing. + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`Response._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + :return: A tuple in the form ``(stream, form, files)``. + """ + return FormDataParser( + stream_factory, + charset, + errors, + max_form_memory_size, + max_content_length, + cls, + silent, + ).parse_from_environ(environ) + + +def exhaust_stream(f: F) -> F: + """Helper decorator for methods that exhausts the stream on return.""" + + def wrapper(self, stream, *args, **kwargs): # type: ignore + try: + return f(self, stream, *args, **kwargs) + finally: + exhaust = getattr(stream, "exhaust", None) + + if exhaust is not None: + exhaust() + else: + while True: + chunk = stream.read(1024 * 64) + + if not chunk: + break + + return update_wrapper(t.cast(F, wrapper), f) + + +class FormDataParser: + """This class implements parsing of form data for Werkzeug. By itself + it can parse multipart and url encoded form data. It can be subclassed + and extended but for most mimetypes it is a better idea to use the + untouched stream and expose it as separate attributes on a request + object. + + .. versionadded:: 0.8 + + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`Response._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + """ + + def __init__( + self, + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + max_content_length: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + silent: bool = True, + ) -> None: + if stream_factory is None: + stream_factory = default_stream_factory + + self.stream_factory = stream_factory + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + self.max_content_length = max_content_length + + if cls is None: + cls = MultiDict + + self.cls = cls + self.silent = silent + + def get_parse_func( + self, mimetype: str, options: t.Dict[str, str] + ) -> t.Optional[ + t.Callable[ + ["FormDataParser", t.IO[bytes], str, t.Optional[int], t.Dict[str, str]], + "t_parse_result", + ] + ]: + return self.parse_functions.get(mimetype) + + def parse_from_environ(self, environ: "WSGIEnvironment") -> "t_parse_result": + """Parses the information from the environment as form data. + + :param environ: the WSGI environment to be used for parsing. + :return: A tuple in the form ``(stream, form, files)``. + """ + content_type = environ.get("CONTENT_TYPE", "") + content_length = get_content_length(environ) + mimetype, options = parse_options_header(content_type) + return self.parse(get_input_stream(environ), mimetype, content_length, options) + + def parse( + self, + stream: t.IO[bytes], + mimetype: str, + content_length: t.Optional[int], + options: t.Optional[t.Dict[str, str]] = None, + ) -> "t_parse_result": + """Parses the information from the given stream, mimetype, + content length and mimetype parameters. + + :param stream: an input stream + :param mimetype: the mimetype of the data + :param content_length: the content length of the incoming data + :param options: optional mimetype parameters (used for + the multipart boundary for instance) + :return: A tuple in the form ``(stream, form, files)``. + """ + if ( + self.max_content_length is not None + and content_length is not None + and content_length > self.max_content_length + ): + # if the input stream is not exhausted, firefox reports Connection Reset + _exhaust(stream) + raise exceptions.RequestEntityTooLarge() + + if options is None: + options = {} + + parse_func = self.get_parse_func(mimetype, options) + + if parse_func is not None: + try: + return parse_func(self, stream, mimetype, content_length, options) + except ValueError: + if not self.silent: + raise + + return stream, self.cls(), self.cls() + + @exhaust_stream + def _parse_multipart( + self, + stream: t.IO[bytes], + mimetype: str, + content_length: t.Optional[int], + options: t.Dict[str, str], + ) -> "t_parse_result": + parser = MultiPartParser( + self.stream_factory, + self.charset, + self.errors, + max_form_memory_size=self.max_form_memory_size, + cls=self.cls, + ) + boundary = options.get("boundary", "").encode("ascii") + + if not boundary: + raise ValueError("Missing boundary") + + form, files = parser.parse(stream, boundary, content_length) + return stream, form, files + + @exhaust_stream + def _parse_urlencoded( + self, + stream: t.IO[bytes], + mimetype: str, + content_length: t.Optional[int], + options: t.Dict[str, str], + ) -> "t_parse_result": + if ( + self.max_form_memory_size is not None + and content_length is not None + and content_length > self.max_form_memory_size + ): + # if the input stream is not exhausted, firefox reports Connection Reset + _exhaust(stream) + raise exceptions.RequestEntityTooLarge() + + form = url_decode_stream(stream, self.charset, errors=self.errors, cls=self.cls) + return stream, form, self.cls() + + #: mapping of mimetypes to parsing functions + parse_functions: t.Dict[ + str, + t.Callable[ + ["FormDataParser", t.IO[bytes], str, t.Optional[int], t.Dict[str, str]], + "t_parse_result", + ], + ] = { + "multipart/form-data": _parse_multipart, + "application/x-www-form-urlencoded": _parse_urlencoded, + "application/x-url-encoded": _parse_urlencoded, + } + + +def _line_parse(line: str) -> t.Tuple[str, bool]: + """Removes line ending characters and returns a tuple (`stripped_line`, + `is_terminated`). + """ + if line[-2:] == "\r\n": + return line[:-2], True + + elif line[-1:] in {"\r", "\n"}: + return line[:-1], True + + return line, False + + +class MultiPartParser: + def __init__( + self, + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + buffer_size: int = 64 * 1024, + ) -> None: + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + + if stream_factory is None: + stream_factory = default_stream_factory + + self.stream_factory = stream_factory + + if cls is None: + cls = MultiDict + + self.cls = cls + + self.buffer_size = buffer_size + + def fail(self, message: str) -> "te.NoReturn": + raise ValueError(message) + + def get_part_charset(self, headers: Headers) -> str: + # Figure out input charset for current part + content_type = headers.get("content-type") + + if content_type: + mimetype, ct_params = parse_options_header(content_type) + return ct_params.get("charset", self.charset) + + return self.charset + + def start_file_streaming( + self, event: File, total_content_length: t.Optional[int] + ) -> t.IO[bytes]: + content_type = event.headers.get("content-type") + + try: + content_length = int(event.headers["content-length"]) + except (KeyError, ValueError): + content_length = 0 + + container = self.stream_factory( + total_content_length=total_content_length, + filename=event.filename, + content_type=content_type, + content_length=content_length, + ) + return container + + def parse( + self, stream: t.IO[bytes], boundary: bytes, content_length: t.Optional[int] + ) -> t.Tuple[MultiDict, MultiDict]: + container: t.Union[t.IO[bytes], t.List[bytes]] + _write: t.Callable[[bytes], t.Any] + + iterator = chain( + _make_chunk_iter( + stream, + limit=content_length, + buffer_size=self.buffer_size, + ), + [None], + ) + + parser = MultipartDecoder(boundary, self.max_form_memory_size) + + fields = [] + files = [] + + current_part: Union[Field, File] + for data in iterator: + parser.receive_data(data) + event = parser.next_event() + while not isinstance(event, (Epilogue, NeedData)): + if isinstance(event, Field): + current_part = event + container = [] + _write = container.append + elif isinstance(event, File): + current_part = event + container = self.start_file_streaming(event, content_length) + _write = container.write + elif isinstance(event, Data): + _write(event.data) + if not event.more_data: + if isinstance(current_part, Field): + value = b"".join(container).decode( + self.get_part_charset(current_part.headers), self.errors + ) + fields.append((current_part.name, value)) + else: + container = t.cast(t.IO[bytes], container) + container.seek(0) + files.append( + ( + current_part.name, + FileStorage( + container, + current_part.filename, + current_part.name, + headers=current_part.headers, + ), + ) + ) + + event = parser.next_event() + + return self.cls(fields), self.cls(files) diff --git a/lib/python3.10/site-packages/werkzeug/http.py b/lib/python3.10/site-packages/werkzeug/http.py new file mode 100644 index 0000000..9777685 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/http.py @@ -0,0 +1,1311 @@ +import base64 +import email.utils +import re +import typing +import typing as t +import warnings +from datetime import date +from datetime import datetime +from datetime import time +from datetime import timedelta +from datetime import timezone +from enum import Enum +from hashlib import sha1 +from time import mktime +from time import struct_time +from urllib.parse import unquote_to_bytes as _unquote +from urllib.request import parse_http_list as _parse_list_header + +from ._internal import _cookie_quote +from ._internal import _dt_as_utc +from ._internal import _make_cookie_domain +from ._internal import _to_bytes +from ._internal import _to_str +from ._internal import _wsgi_decoding_dance + +if t.TYPE_CHECKING: + from _typeshed.wsgi import WSGIEnvironment + +# for explanation of "media-range", etc. see Sections 5.3.{1,2} of RFC 7231 +_accept_re = re.compile( + r""" + ( # media-range capturing-parenthesis + [^\s;,]+ # type/subtype + (?:[ \t]*;[ \t]* # ";" + (?: # parameter non-capturing-parenthesis + [^\s;,q][^\s;,]* # token that doesn't start with "q" + | # or + q[^\s;,=][^\s;,]* # token that is more than just "q" + ) + )* # zero or more parameters + ) # end of media-range + (?:[ \t]*;[ \t]*q= # weight is a "q" parameter + (\d*(?:\.\d+)?) # qvalue capturing-parentheses + [^,]* # "extension" accept params: who cares? + )? # accept params are optional + """, + re.VERBOSE, +) +_token_chars = frozenset( + "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~" +) +_etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)') +_option_header_piece_re = re.compile( + r""" + ;\s*,?\s* # newlines were replaced with commas + (?P + "[^"\\]*(?:\\.[^"\\]*)*" # quoted string + | + [^\s;,=*]+ # token + ) + (?:\*(?P\d+))? # *1, optional continuation index + \s* + (?: # optionally followed by =value + (?: # equals sign, possibly with encoding + \*\s*=\s* # * indicates extended notation + (?: # optional encoding + (?P[^\s]+?) + '(?P[^\s]*?)' + )? + | + =\s* # basic notation + ) + (?P + "[^"\\]*(?:\\.[^"\\]*)*" # quoted string + | + [^;,]+ # token + )? + )? + \s* + """, + flags=re.VERBOSE, +) +_option_header_start_mime_type = re.compile(r",\s*([^;,\s]+)([;,]\s*.+)?") +_entity_headers = frozenset( + [ + "allow", + "content-encoding", + "content-language", + "content-length", + "content-location", + "content-md5", + "content-range", + "content-type", + "expires", + "last-modified", + ] +) +_hop_by_hop_headers = frozenset( + [ + "connection", + "keep-alive", + "proxy-authenticate", + "proxy-authorization", + "te", + "trailer", + "transfer-encoding", + "upgrade", + ] +) +HTTP_STATUS_CODES = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 103: "Early Hints", # see RFC 8297 + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi Status", + 208: "Already Reported", # see RFC 5842 + 226: "IM Used", # see RFC 3229 + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", # unused + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", # unused + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", # see RFC 2324 + 421: "Misdirected Request", # see RFC 7540 + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 425: "Too Early", # see RFC 8470 + 426: "Upgrade Required", + 428: "Precondition Required", # see RFC 6585 + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 449: "Retry With", # proprietary MS extension + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", # see RFC 2295 + 507: "Insufficient Storage", + 508: "Loop Detected", # see RFC 5842 + 510: "Not Extended", + 511: "Network Authentication Failed", +} + + +class COEP(Enum): + """Cross Origin Embedder Policies""" + + UNSAFE_NONE = "unsafe-none" + REQUIRE_CORP = "require-corp" + + +class COOP(Enum): + """Cross Origin Opener Policies""" + + UNSAFE_NONE = "unsafe-none" + SAME_ORIGIN_ALLOW_POPUPS = "same-origin-allow-popups" + SAME_ORIGIN = "same-origin" + + +def quote_header_value( + value: t.Union[str, int], extra_chars: str = "", allow_token: bool = True +) -> str: + """Quote a header value if necessary. + + .. versionadded:: 0.5 + + :param value: the value to quote. + :param extra_chars: a list of extra characters to skip quoting. + :param allow_token: if this is enabled token values are returned + unchanged. + """ + if isinstance(value, bytes): + value = value.decode("latin1") + value = str(value) + if allow_token: + token_chars = _token_chars | set(extra_chars) + if set(value).issubset(token_chars): + return value + value = value.replace("\\", "\\\\").replace('"', '\\"') + return f'"{value}"' + + +def unquote_header_value(value: str, is_filename: bool = False) -> str: + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + .. versionadded:: 0.5 + + :param value: the header value to unquote. + :param is_filename: The value represents a filename or path. + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != "\\\\": + return value.replace("\\\\", "\\").replace('\\"', '"') + return value + + +def dump_options_header( + header: t.Optional[str], options: t.Mapping[str, t.Optional[t.Union[str, int]]] +) -> str: + """The reverse function to :func:`parse_options_header`. + + :param header: the header to dump + :param options: a dict of options to append. + """ + segments = [] + if header is not None: + segments.append(header) + for key, value in options.items(): + if value is None: + segments.append(key) + else: + segments.append(f"{key}={quote_header_value(value)}") + return "; ".join(segments) + + +def dump_header( + iterable: t.Union[t.Dict[str, t.Union[str, int]], t.Iterable[str]], + allow_token: bool = True, +) -> str: + """Dump an HTTP header again. This is the reversal of + :func:`parse_list_header`, :func:`parse_set_header` and + :func:`parse_dict_header`. This also quotes strings that include an + equals sign unless you pass it as dict of key, value pairs. + + >>> dump_header({'foo': 'bar baz'}) + 'foo="bar baz"' + >>> dump_header(('foo', 'bar baz')) + 'foo, "bar baz"' + + :param iterable: the iterable or dict of values to quote. + :param allow_token: if set to `False` tokens as values are disallowed. + See :func:`quote_header_value` for more details. + """ + if isinstance(iterable, dict): + items = [] + for key, value in iterable.items(): + if value is None: + items.append(key) + else: + items.append( + f"{key}={quote_header_value(value, allow_token=allow_token)}" + ) + else: + items = [quote_header_value(x, allow_token=allow_token) for x in iterable] + return ", ".join(items) + + +def dump_csp_header(header: "ds.ContentSecurityPolicy") -> str: + """Dump a Content Security Policy header. + + These are structured into policies such as "default-src 'self'; + script-src 'self'". + + .. versionadded:: 1.0.0 + Support for Content Security Policy headers was added. + + """ + return "; ".join(f"{key} {value}" for key, value in header.items()) + + +def parse_list_header(value: str) -> t.List[str]: + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +def parse_dict_header(value: str, cls: t.Type[dict] = dict) -> t.Dict[str, str]: + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict (or any other mapping object created from + the type with a dict like interface provided by the `cls` argument): + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + .. versionchanged:: 0.9 + Added support for `cls` argument. + + :param value: a string with a dict header. + :param cls: callable to use for storage of parsed results. + :return: an instance of `cls` + """ + result = cls() + if isinstance(value, bytes): + value = value.decode("latin1") + for item in _parse_list_header(value): + if "=" not in item: + result[item] = None + continue + name, value = item.split("=", 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +def parse_options_header(value: t.Optional[str]) -> t.Tuple[str, t.Dict[str, str]]: + """Parse a ``Content-Type``-like header into a tuple with the + value and any options: + + >>> parse_options_header('text/html; charset=utf8') + ('text/html', {'charset': 'utf8'}) + + This should is not for ``Cache-Control``-like headers, which use a + different format. For those, use :func:`parse_dict_header`. + + :param value: The header value to parse. + + .. versionchanged:: 2.2 + Option names are always converted to lowercase. + + .. versionchanged:: 2.1 + The ``multiple`` parameter is deprecated and will be removed in + Werkzeug 2.2. + + .. versionchanged:: 0.15 + :rfc:`2231` parameter continuations are handled. + + .. versionadded:: 0.5 + """ + if not value: + return "", {} + + result: t.List[t.Any] = [] + + value = "," + value.replace("\n", ",") + while value: + match = _option_header_start_mime_type.match(value) + if not match: + break + result.append(match.group(1)) # mimetype + options: t.Dict[str, str] = {} + # Parse options + rest = match.group(2) + encoding: t.Optional[str] + continued_encoding: t.Optional[str] = None + while rest: + optmatch = _option_header_piece_re.match(rest) + if not optmatch: + break + option, count, encoding, language, option_value = optmatch.groups() + # Continuations don't have to supply the encoding after the + # first line. If we're in a continuation, track the current + # encoding to use for subsequent lines. Reset it when the + # continuation ends. + if not count: + continued_encoding = None + else: + if not encoding: + encoding = continued_encoding + continued_encoding = encoding + option = unquote_header_value(option).lower() + + if option_value is not None: + option_value = unquote_header_value(option_value, option == "filename") + + if encoding is not None: + option_value = _unquote(option_value).decode(encoding) + + if count: + # Continuations append to the existing value. For + # simplicity, this ignores the possibility of + # out-of-order indices, which shouldn't happen anyway. + if option_value is not None: + options[option] = options.get(option, "") + option_value + else: + options[option] = option_value # type: ignore[assignment] + + rest = rest[optmatch.end() :] + result.append(options) + return tuple(result) # type: ignore[return-value] + + return tuple(result) if result else ("", {}) # type: ignore[return-value] + + +_TAnyAccept = t.TypeVar("_TAnyAccept", bound="ds.Accept") + + +@typing.overload +def parse_accept_header(value: t.Optional[str]) -> "ds.Accept": + ... + + +@typing.overload +def parse_accept_header( + value: t.Optional[str], cls: t.Type[_TAnyAccept] +) -> _TAnyAccept: + ... + + +def parse_accept_header( + value: t.Optional[str], cls: t.Optional[t.Type[_TAnyAccept]] = None +) -> _TAnyAccept: + """Parses an HTTP Accept-* header. This does not implement a complete + valid algorithm but one that supports at least value and quality + extraction. + + Returns a new :class:`Accept` object (basically a list of ``(value, quality)`` + tuples sorted by the quality with some additional accessor methods). + + The second parameter can be a subclass of :class:`Accept` that is created + with the parsed values and returned. + + :param value: the accept header string to be parsed. + :param cls: the wrapper class for the return value (can be + :class:`Accept` or a subclass thereof) + :return: an instance of `cls`. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyAccept], ds.Accept) + + if not value: + return cls(None) + + result = [] + for match in _accept_re.finditer(value): + quality_match = match.group(2) + if not quality_match: + quality: float = 1 + else: + quality = max(min(float(quality_match), 1), 0) + result.append((match.group(1), quality)) + return cls(result) + + +_TAnyCC = t.TypeVar("_TAnyCC", bound="ds._CacheControl") +_t_cc_update = t.Optional[t.Callable[[_TAnyCC], None]] + + +@typing.overload +def parse_cache_control_header( + value: t.Optional[str], on_update: _t_cc_update, cls: None = None +) -> "ds.RequestCacheControl": + ... + + +@typing.overload +def parse_cache_control_header( + value: t.Optional[str], on_update: _t_cc_update, cls: t.Type[_TAnyCC] +) -> _TAnyCC: + ... + + +def parse_cache_control_header( + value: t.Optional[str], + on_update: _t_cc_update = None, + cls: t.Optional[t.Type[_TAnyCC]] = None, +) -> _TAnyCC: + """Parse a cache control header. The RFC differs between response and + request cache control, this method does not. It's your responsibility + to not use the wrong control statements. + + .. versionadded:: 0.5 + The `cls` was added. If not specified an immutable + :class:`~werkzeug.datastructures.RequestCacheControl` is returned. + + :param value: a cache control header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.CacheControl` + object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.RequestCacheControl` is used. + :return: a `cls` object. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyCC], ds.RequestCacheControl) + + if not value: + return cls((), on_update) + + return cls(parse_dict_header(value), on_update) + + +_TAnyCSP = t.TypeVar("_TAnyCSP", bound="ds.ContentSecurityPolicy") +_t_csp_update = t.Optional[t.Callable[[_TAnyCSP], None]] + + +@typing.overload +def parse_csp_header( + value: t.Optional[str], on_update: _t_csp_update, cls: None = None +) -> "ds.ContentSecurityPolicy": + ... + + +@typing.overload +def parse_csp_header( + value: t.Optional[str], on_update: _t_csp_update, cls: t.Type[_TAnyCSP] +) -> _TAnyCSP: + ... + + +def parse_csp_header( + value: t.Optional[str], + on_update: _t_csp_update = None, + cls: t.Optional[t.Type[_TAnyCSP]] = None, +) -> _TAnyCSP: + """Parse a Content Security Policy header. + + .. versionadded:: 1.0.0 + Support for Content Security Policy headers was added. + + :param value: a csp header to be parsed. + :param on_update: an optional callable that is called every time a value + on the object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.ContentSecurityPolicy` is used. + :return: a `cls` object. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyCSP], ds.ContentSecurityPolicy) + + if value is None: + return cls((), on_update) + + items = [] + + for policy in value.split(";"): + policy = policy.strip() + + # Ignore badly formatted policies (no space) + if " " in policy: + directive, value = policy.strip().split(" ", 1) + items.append((directive.strip(), value.strip())) + + return cls(items, on_update) + + +def parse_set_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.HeaderSet"], None]] = None, +) -> "ds.HeaderSet": + """Parse a set-like header and return a + :class:`~werkzeug.datastructures.HeaderSet` object: + + >>> hs = parse_set_header('token, "quoted value"') + + The return value is an object that treats the items case-insensitively + and keeps the order of the items: + + >>> 'TOKEN' in hs + True + >>> hs.index('quoted value') + 1 + >>> hs + HeaderSet(['token', 'quoted value']) + + To create a header from the :class:`HeaderSet` again, use the + :func:`dump_header` function. + + :param value: a set header to be parsed. + :param on_update: an optional callable that is called every time a + value on the :class:`~werkzeug.datastructures.HeaderSet` + object is changed. + :return: a :class:`~werkzeug.datastructures.HeaderSet` + """ + if not value: + return ds.HeaderSet(None, on_update) + return ds.HeaderSet(parse_list_header(value), on_update) + + +def parse_authorization_header( + value: t.Optional[str], +) -> t.Optional["ds.Authorization"]: + """Parse an HTTP basic/digest authorization header transmitted by the web + browser. The return value is either `None` if the header was invalid or + not given, otherwise an :class:`~werkzeug.datastructures.Authorization` + object. + + :param value: the authorization header to parse. + :return: a :class:`~werkzeug.datastructures.Authorization` object or `None`. + """ + if not value: + return None + value = _wsgi_decoding_dance(value) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except ValueError: + return None + if auth_type == "basic": + try: + username, password = base64.b64decode(auth_info).split(b":", 1) + except Exception: + return None + try: + return ds.Authorization( + "basic", + { + "username": _to_str(username, "utf-8"), + "password": _to_str(password, "utf-8"), + }, + ) + except UnicodeDecodeError: + return None + elif auth_type == "digest": + auth_map = parse_dict_header(auth_info) + for key in "username", "realm", "nonce", "uri", "response": + if key not in auth_map: + return None + if "qop" in auth_map: + if not auth_map.get("nc") or not auth_map.get("cnonce"): + return None + return ds.Authorization("digest", auth_map) + return None + + +def parse_www_authenticate_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.WWWAuthenticate"], None]] = None, +) -> "ds.WWWAuthenticate": + """Parse an HTTP WWW-Authenticate header into a + :class:`~werkzeug.datastructures.WWWAuthenticate` object. + + :param value: a WWW-Authenticate header to parse. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.WWWAuthenticate` + object is changed. + :return: a :class:`~werkzeug.datastructures.WWWAuthenticate` object. + """ + if not value: + return ds.WWWAuthenticate(on_update=on_update) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except (ValueError, AttributeError): + return ds.WWWAuthenticate(value.strip().lower(), on_update=on_update) + return ds.WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update) + + +def parse_if_range_header(value: t.Optional[str]) -> "ds.IfRange": + """Parses an if-range header which can be an etag or a date. Returns + a :class:`~werkzeug.datastructures.IfRange` object. + + .. versionchanged:: 2.0 + If the value represents a datetime, it is timezone-aware. + + .. versionadded:: 0.7 + """ + if not value: + return ds.IfRange() + date = parse_date(value) + if date is not None: + return ds.IfRange(date=date) + # drop weakness information + return ds.IfRange(unquote_etag(value)[0]) + + +def parse_range_header( + value: t.Optional[str], make_inclusive: bool = True +) -> t.Optional["ds.Range"]: + """Parses a range header into a :class:`~werkzeug.datastructures.Range` + object. If the header is missing or malformed `None` is returned. + `ranges` is a list of ``(start, stop)`` tuples where the ranges are + non-inclusive. + + .. versionadded:: 0.7 + """ + if not value or "=" not in value: + return None + + ranges = [] + last_end = 0 + units, rng = value.split("=", 1) + units = units.strip().lower() + + for item in rng.split(","): + item = item.strip() + if "-" not in item: + return None + if item.startswith("-"): + if last_end < 0: + return None + try: + begin = int(item) + except ValueError: + return None + end = None + last_end = -1 + elif "-" in item: + begin_str, end_str = item.split("-", 1) + begin_str = begin_str.strip() + end_str = end_str.strip() + + try: + begin = int(begin_str) + except ValueError: + return None + + if begin < last_end or last_end < 0: + return None + if end_str: + try: + end = int(end_str) + 1 + except ValueError: + return None + + if begin >= end: + return None + else: + end = None + last_end = end if end is not None else -1 + ranges.append((begin, end)) + + return ds.Range(units, ranges) + + +def parse_content_range_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.ContentRange"], None]] = None, +) -> t.Optional["ds.ContentRange"]: + """Parses a range header into a + :class:`~werkzeug.datastructures.ContentRange` object or `None` if + parsing is not possible. + + .. versionadded:: 0.7 + + :param value: a content range header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.ContentRange` + object is changed. + """ + if value is None: + return None + try: + units, rangedef = (value or "").strip().split(None, 1) + except ValueError: + return None + + if "/" not in rangedef: + return None + rng, length_str = rangedef.split("/", 1) + if length_str == "*": + length = None + else: + try: + length = int(length_str) + except ValueError: + return None + + if rng == "*": + return ds.ContentRange(units, None, None, length, on_update=on_update) + elif "-" not in rng: + return None + + start_str, stop_str = rng.split("-", 1) + try: + start = int(start_str) + stop = int(stop_str) + 1 + except ValueError: + return None + + if is_byte_range_valid(start, stop, length): + return ds.ContentRange(units, start, stop, length, on_update=on_update) + + return None + + +def quote_etag(etag: str, weak: bool = False) -> str: + """Quote an etag. + + :param etag: the etag to quote. + :param weak: set to `True` to tag it "weak". + """ + if '"' in etag: + raise ValueError("invalid etag") + etag = f'"{etag}"' + if weak: + etag = f"W/{etag}" + return etag + + +def unquote_etag( + etag: t.Optional[str], +) -> t.Union[t.Tuple[str, bool], t.Tuple[None, None]]: + """Unquote a single etag: + + >>> unquote_etag('W/"bar"') + ('bar', True) + >>> unquote_etag('"bar"') + ('bar', False) + + :param etag: the etag identifier to unquote. + :return: a ``(etag, weak)`` tuple. + """ + if not etag: + return None, None + etag = etag.strip() + weak = False + if etag.startswith(("W/", "w/")): + weak = True + etag = etag[2:] + if etag[:1] == etag[-1:] == '"': + etag = etag[1:-1] + return etag, weak + + +def parse_etags(value: t.Optional[str]) -> "ds.ETags": + """Parse an etag header. + + :param value: the tag header to parse + :return: an :class:`~werkzeug.datastructures.ETags` object. + """ + if not value: + return ds.ETags() + strong = [] + weak = [] + end = len(value) + pos = 0 + while pos < end: + match = _etag_re.match(value, pos) + if match is None: + break + is_weak, quoted, raw = match.groups() + if raw == "*": + return ds.ETags(star_tag=True) + elif quoted: + raw = quoted + if is_weak: + weak.append(raw) + else: + strong.append(raw) + pos = match.end() + return ds.ETags(strong, weak) + + +def generate_etag(data: bytes) -> str: + """Generate an etag for some data. + + .. versionchanged:: 2.0 + Use SHA-1. MD5 may not be available in some environments. + """ + return sha1(data).hexdigest() + + +def parse_date(value: t.Optional[str]) -> t.Optional[datetime]: + """Parse an :rfc:`2822` date into a timezone-aware + :class:`datetime.datetime` object, or ``None`` if parsing fails. + + This is a wrapper for :func:`email.utils.parsedate_to_datetime`. It + returns ``None`` if parsing fails instead of raising an exception, + and always returns a timezone-aware datetime object. If the string + doesn't have timezone information, it is assumed to be UTC. + + :param value: A string with a supported date format. + + .. versionchanged:: 2.0 + Return a timezone-aware datetime object. Use + ``email.utils.parsedate_to_datetime``. + """ + if value is None: + return None + + try: + dt = email.utils.parsedate_to_datetime(value) + except (TypeError, ValueError): + return None + + if dt.tzinfo is None: + return dt.replace(tzinfo=timezone.utc) + + return dt + + +def http_date( + timestamp: t.Optional[t.Union[datetime, date, int, float, struct_time]] = None +) -> str: + """Format a datetime object or timestamp into an :rfc:`2822` date + string. + + This is a wrapper for :func:`email.utils.format_datetime`. It + assumes naive datetime objects are in UTC instead of raising an + exception. + + :param timestamp: The datetime or timestamp to format. Defaults to + the current time. + + .. versionchanged:: 2.0 + Use ``email.utils.format_datetime``. Accept ``date`` objects. + """ + if isinstance(timestamp, date): + if not isinstance(timestamp, datetime): + # Assume plain date is midnight UTC. + timestamp = datetime.combine(timestamp, time(), tzinfo=timezone.utc) + else: + # Ensure datetime is timezone-aware. + timestamp = _dt_as_utc(timestamp) + + return email.utils.format_datetime(timestamp, usegmt=True) + + if isinstance(timestamp, struct_time): + timestamp = mktime(timestamp) + + return email.utils.formatdate(timestamp, usegmt=True) + + +def parse_age(value: t.Optional[str] = None) -> t.Optional[timedelta]: + """Parses a base-10 integer count of seconds into a timedelta. + + If parsing fails, the return value is `None`. + + :param value: a string consisting of an integer represented in base-10 + :return: a :class:`datetime.timedelta` object or `None`. + """ + if not value: + return None + try: + seconds = int(value) + except ValueError: + return None + if seconds < 0: + return None + try: + return timedelta(seconds=seconds) + except OverflowError: + return None + + +def dump_age(age: t.Optional[t.Union[timedelta, int]] = None) -> t.Optional[str]: + """Formats the duration as a base-10 integer. + + :param age: should be an integer number of seconds, + a :class:`datetime.timedelta` object, or, + if the age is unknown, `None` (default). + """ + if age is None: + return None + if isinstance(age, timedelta): + age = int(age.total_seconds()) + else: + age = int(age) + + if age < 0: + raise ValueError("age cannot be negative") + + return str(age) + + +def is_resource_modified( + environ: "WSGIEnvironment", + etag: t.Optional[str] = None, + data: t.Optional[bytes] = None, + last_modified: t.Optional[t.Union[datetime, str]] = None, + ignore_if_range: bool = True, +) -> bool: + """Convenience method for conditional requests. + + :param environ: the WSGI environment of the request to be checked. + :param etag: the etag for the response for comparison. + :param data: or alternatively the data of the response to automatically + generate an etag using :func:`generate_etag`. + :param last_modified: an optional date of the last modification. + :param ignore_if_range: If `False`, `If-Range` header will be taken into + account. + :return: `True` if the resource was modified, otherwise `False`. + + .. versionchanged:: 2.0 + SHA-1 is used to generate an etag value for the data. MD5 may + not be available in some environments. + + .. versionchanged:: 1.0.0 + The check is run for methods other than ``GET`` and ``HEAD``. + """ + return _sansio_http.is_resource_modified( + http_range=environ.get("HTTP_RANGE"), + http_if_range=environ.get("HTTP_IF_RANGE"), + http_if_modified_since=environ.get("HTTP_IF_MODIFIED_SINCE"), + http_if_none_match=environ.get("HTTP_IF_NONE_MATCH"), + http_if_match=environ.get("HTTP_IF_MATCH"), + etag=etag, + data=data, + last_modified=last_modified, + ignore_if_range=ignore_if_range, + ) + + +def remove_entity_headers( + headers: t.Union["ds.Headers", t.List[t.Tuple[str, str]]], + allowed: t.Iterable[str] = ("expires", "content-location"), +) -> None: + """Remove all entity headers from a list or :class:`Headers` object. This + operation works in-place. `Expires` and `Content-Location` headers are + by default not removed. The reason for this is :rfc:`2616` section + 10.3.5 which specifies some entity headers that should be sent. + + .. versionchanged:: 0.5 + added `allowed` parameter. + + :param headers: a list or :class:`Headers` object. + :param allowed: a list of headers that should still be allowed even though + they are entity headers. + """ + allowed = {x.lower() for x in allowed} + headers[:] = [ + (key, value) + for key, value in headers + if not is_entity_header(key) or key.lower() in allowed + ] + + +def remove_hop_by_hop_headers( + headers: t.Union["ds.Headers", t.List[t.Tuple[str, str]]] +) -> None: + """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or + :class:`Headers` object. This operation works in-place. + + .. versionadded:: 0.5 + + :param headers: a list or :class:`Headers` object. + """ + headers[:] = [ + (key, value) for key, value in headers if not is_hop_by_hop_header(key) + ] + + +def is_entity_header(header: str) -> bool: + """Check if a header is an entity header. + + .. versionadded:: 0.5 + + :param header: the header to test. + :return: `True` if it's an entity header, `False` otherwise. + """ + return header.lower() in _entity_headers + + +def is_hop_by_hop_header(header: str) -> bool: + """Check if a header is an HTTP/1.1 "Hop-by-Hop" header. + + .. versionadded:: 0.5 + + :param header: the header to test. + :return: `True` if it's an HTTP/1.1 "Hop-by-Hop" header, `False` otherwise. + """ + return header.lower() in _hop_by_hop_headers + + +def parse_cookie( + header: t.Union["WSGIEnvironment", str, bytes, None], + charset: str = "utf-8", + errors: str = "replace", + cls: t.Optional[t.Type["ds.MultiDict"]] = None, +) -> "ds.MultiDict[str, str]": + """Parse a cookie from a string or WSGI environ. + + The same key can be provided multiple times, the values are stored + in-order. The default :class:`MultiDict` will have the first value + first, and all values can be retrieved with + :meth:`MultiDict.getlist`. + + :param header: The cookie header as a string, or a WSGI environ dict + with a ``HTTP_COOKIE`` key. + :param charset: The charset for the cookie values. + :param errors: The error behavior for the charset decoding. + :param cls: A dict-like class to store the parsed cookies in. + Defaults to :class:`MultiDict`. + + .. versionchanged:: 1.0.0 + Returns a :class:`MultiDict` instead of a + ``TypeConversionDict``. + + .. versionchanged:: 0.5 + Returns a :class:`TypeConversionDict` instead of a regular dict. + The ``cls`` parameter was added. + """ + if isinstance(header, dict): + cookie = header.get("HTTP_COOKIE", "") + elif header is None: + cookie = "" + else: + cookie = header + + return _sansio_http.parse_cookie( + cookie=cookie, charset=charset, errors=errors, cls=cls + ) + + +def dump_cookie( + key: str, + value: t.Union[bytes, str] = "", + max_age: t.Optional[t.Union[timedelta, int]] = None, + expires: t.Optional[t.Union[str, datetime, int, float]] = None, + path: t.Optional[str] = "/", + domain: t.Optional[str] = None, + secure: bool = False, + httponly: bool = False, + charset: str = "utf-8", + sync_expires: bool = True, + max_size: int = 4093, + samesite: t.Optional[str] = None, +) -> str: + """Create a Set-Cookie header without the ``Set-Cookie`` prefix. + + The return value is usually restricted to ascii as the vast majority + of values are properly escaped, but that is no guarantee. It's + tunneled through latin1 as required by :pep:`3333`. + + The return value is not ASCII safe if the key contains unicode + characters. This is technically against the specification but + happens in the wild. It's strongly recommended to not use + non-ASCII values for the keys. + + :param max_age: should be a number of seconds, or `None` (default) if + the cookie should last only as long as the client's + browser session. Additionally `timedelta` objects + are accepted, too. + :param expires: should be a `datetime` object or unix timestamp. + :param path: limits the cookie to a given path, per default it will + span the whole domain. + :param domain: Use this if you want to set a cross-domain cookie. For + example, ``domain=".example.com"`` will set a cookie + that is readable by the domain ``www.example.com``, + ``foo.example.com`` etc. Otherwise, a cookie will only + be readable by the domain that set it. + :param secure: The cookie will only be available via HTTPS + :param httponly: disallow JavaScript to access the cookie. This is an + extension to the cookie standard and probably not + supported by all browsers. + :param charset: the encoding for string values. + :param sync_expires: automatically set expires if max_age is defined + but expires not. + :param max_size: Warn if the final header value exceeds this size. The + default, 4093, should be safely `supported by most browsers + `_. Set to 0 to disable this check. + :param samesite: Limits the scope of the cookie such that it will + only be attached to requests if those requests are same-site. + + .. _`cookie`: http://browsercookielimits.squawky.net/ + + .. versionchanged:: 1.0.0 + The string ``'None'`` is accepted for ``samesite``. + """ + key = _to_bytes(key, charset) + value = _to_bytes(value, charset) + + if path is not None: + from .urls import iri_to_uri + + path = iri_to_uri(path, charset) + + domain = _make_cookie_domain(domain) + + if isinstance(max_age, timedelta): + max_age = int(max_age.total_seconds()) + + if expires is not None: + if not isinstance(expires, str): + expires = http_date(expires) + elif max_age is not None and sync_expires: + expires = http_date(datetime.now(tz=timezone.utc).timestamp() + max_age) + + if samesite is not None: + samesite = samesite.title() + + if samesite not in {"Strict", "Lax", "None"}: + raise ValueError("SameSite must be 'Strict', 'Lax', or 'None'.") + + buf = [key + b"=" + _cookie_quote(value)] + + # XXX: In theory all of these parameters that are not marked with `None` + # should be quoted. Because stdlib did not quote it before I did not + # want to introduce quoting there now. + for k, v, q in ( + (b"Domain", domain, True), + (b"Expires", expires, False), + (b"Max-Age", max_age, False), + (b"Secure", secure, None), + (b"HttpOnly", httponly, None), + (b"Path", path, False), + (b"SameSite", samesite, False), + ): + if q is None: + if v: + buf.append(k) + continue + + if v is None: + continue + + tmp = bytearray(k) + if not isinstance(v, (bytes, bytearray)): + v = _to_bytes(str(v), charset) + if q: + v = _cookie_quote(v) + tmp += b"=" + v + buf.append(bytes(tmp)) + + # The return value will be an incorrectly encoded latin1 header for + # consistency with the headers object. + rv = b"; ".join(buf) + rv = rv.decode("latin1") + + # Warn if the final value of the cookie is larger than the limit. If the + # cookie is too large, then it may be silently ignored by the browser, + # which can be quite hard to debug. + cookie_size = len(rv) + + if max_size and cookie_size > max_size: + value_size = len(value) + warnings.warn( + f"The {key.decode(charset)!r} cookie is too large: the value was" + f" {value_size} bytes but the" + f" header required {cookie_size - value_size} extra bytes. The final size" + f" was {cookie_size} bytes but the limit is {max_size} bytes. Browsers may" + f" silently ignore cookies larger than this.", + stacklevel=2, + ) + + return rv + + +def is_byte_range_valid( + start: t.Optional[int], stop: t.Optional[int], length: t.Optional[int] +) -> bool: + """Checks if a given byte content range is valid for the given length. + + .. versionadded:: 0.7 + """ + if (start is None) != (stop is None): + return False + elif start is None: + return length is None or length >= 0 + elif length is None: + return 0 <= start < stop # type: ignore + elif start >= stop: # type: ignore + return False + return 0 <= start < length + + +# circular dependencies +from . import datastructures as ds +from .sansio import http as _sansio_http diff --git a/lib/python3.10/site-packages/werkzeug/local.py b/lib/python3.10/site-packages/werkzeug/local.py new file mode 100644 index 0000000..70e9bf7 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/local.py @@ -0,0 +1,648 @@ +import copy +import math +import operator +import typing as t +from contextvars import ContextVar +from functools import partial +from functools import update_wrapper +from operator import attrgetter + +from .wsgi import ClosingIterator + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + +T = t.TypeVar("T") +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def release_local(local: t.Union["Local", "LocalStack"]) -> None: + """Release the data for the current context in a :class:`Local` or + :class:`LocalStack` without using a :class:`LocalManager`. + + This should not be needed for modern use cases, and may be removed + in the future. + + .. versionadded:: 0.6.1 + """ + local.__release_local__() + + +class Local: + """Create a namespace of context-local data. This wraps a + :class:`ContextVar` containing a :class:`dict` value. + + This may incur a performance penalty compared to using individual + context vars, as it has to copy data to avoid mutating the dict + between nested contexts. + + :param context_var: The :class:`~contextvars.ContextVar` to use as + storage for this local. If not given, one will be created. + Context vars not created at the global scope may interfere with + garbage collection. + + .. versionchanged:: 2.0 + Uses ``ContextVar`` instead of a custom storage implementation. + """ + + __slots__ = ("__storage",) + + def __init__( + self, context_var: t.Optional[ContextVar[t.Dict[str, t.Any]]] = None + ) -> None: + if context_var is None: + # A ContextVar not created at global scope interferes with + # Python's garbage collection. However, a local only makes + # sense defined at the global scope as well, in which case + # the GC issue doesn't seem relevant. + context_var = ContextVar(f"werkzeug.Local<{id(self)}>.storage") + + object.__setattr__(self, "_Local__storage", context_var) + + def __iter__(self) -> t.Iterator[t.Tuple[str, t.Any]]: + return iter(self.__storage.get({}).items()) + + def __call__( + self, name: str, *, unbound_message: t.Optional[str] = None + ) -> "LocalProxy": + """Create a :class:`LocalProxy` that access an attribute on this + local namespace. + + :param name: Proxy this attribute. + :param unbound_message: The error message that the proxy will + show if the attribute isn't set. + """ + return LocalProxy(self, name, unbound_message=unbound_message) + + def __release_local__(self) -> None: + self.__storage.set({}) + + def __getattr__(self, name: str) -> t.Any: + values = self.__storage.get({}) + + if name in values: + return values[name] + + raise AttributeError(name) + + def __setattr__(self, name: str, value: t.Any) -> None: + values = self.__storage.get({}).copy() + values[name] = value + self.__storage.set(values) + + def __delattr__(self, name: str) -> None: + values = self.__storage.get({}) + + if name in values: + values = values.copy() + del values[name] + self.__storage.set(values) + else: + raise AttributeError(name) + + +class LocalStack(t.Generic[T]): + """Create a stack of context-local data. This wraps a + :class:`ContextVar` containing a :class:`list` value. + + This may incur a performance penalty compared to using individual + context vars, as it has to copy data to avoid mutating the list + between nested contexts. + + :param context_var: The :class:`~contextvars.ContextVar` to use as + storage for this local. If not given, one will be created. + Context vars not created at the global scope may interfere with + garbage collection. + + .. versionchanged:: 2.0 + Uses ``ContextVar`` instead of a custom storage implementation. + + .. versionadded:: 0.6.1 + """ + + __slots__ = ("_storage",) + + def __init__(self, context_var: t.Optional[ContextVar[t.List[T]]] = None) -> None: + if context_var is None: + # A ContextVar not created at global scope interferes with + # Python's garbage collection. However, a local only makes + # sense defined at the global scope as well, in which case + # the GC issue doesn't seem relevant. + context_var = ContextVar(f"werkzeug.LocalStack<{id(self)}>.storage") + + self._storage = context_var + + def __release_local__(self) -> None: + self._storage.set([]) + + def push(self, obj: T) -> t.List[T]: + """Add a new item to the top of the stack.""" + stack = self._storage.get([]).copy() + stack.append(obj) + self._storage.set(stack) + return stack + + def pop(self) -> t.Optional[T]: + """Remove the top item from the stack and return it. If the + stack is empty, return ``None``. + """ + stack = self._storage.get([]) + + if len(stack) == 0: + return None + + rv = stack[-1] + self._storage.set(stack[:-1]) + return rv + + @property + def top(self) -> t.Optional[T]: + """The topmost item on the stack. If the stack is empty, + `None` is returned. + """ + stack = self._storage.get([]) + + if len(stack) == 0: + return None + + return stack[-1] + + def __call__( + self, name: t.Optional[str] = None, *, unbound_message: t.Optional[str] = None + ) -> "LocalProxy": + """Create a :class:`LocalProxy` that accesses the top of this + local stack. + + :param name: If given, the proxy access this attribute of the + top item, rather than the item itself. + :param unbound_message: The error message that the proxy will + show if the stack is empty. + """ + return LocalProxy(self, name, unbound_message=unbound_message) + + +class LocalManager: + """Manage releasing the data for the current context in one or more + :class:`Local` and :class:`LocalStack` objects. + + This should not be needed for modern use cases, and may be removed + in the future. + + :param locals: A local or list of locals to manage. + + .. versionchanged:: 2.0 + ``ident_func`` is deprecated and will be removed in Werkzeug + 2.1. + + .. versionchanged:: 0.7 + The ``ident_func`` parameter was added. + + .. versionchanged:: 0.6.1 + The :func:`release_local` function can be used instead of a + manager. + """ + + __slots__ = ("locals",) + + def __init__( + self, + locals: t.Optional[ + t.Union[Local, LocalStack, t.Iterable[t.Union[Local, LocalStack]]] + ] = None, + ) -> None: + if locals is None: + self.locals = [] + elif isinstance(locals, Local): + self.locals = [locals] + else: + self.locals = list(locals) # type: ignore[arg-type] + + def cleanup(self) -> None: + """Release the data in the locals for this context. Call this at + the end of each request or use :meth:`make_middleware`. + """ + for local in self.locals: + release_local(local) + + def make_middleware(self, app: "WSGIApplication") -> "WSGIApplication": + """Wrap a WSGI application so that local data is released + automatically after the response has been sent for a request. + """ + + def application( + environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + return ClosingIterator(app(environ, start_response), self.cleanup) + + return application + + def middleware(self, func: "WSGIApplication") -> "WSGIApplication": + """Like :meth:`make_middleware` but used as a decorator on the + WSGI application function. + + .. code-block:: python + + @manager.middleware + def application(environ, start_response): + ... + """ + return update_wrapper(self.make_middleware(func), func) + + def __repr__(self) -> str: + return f"<{type(self).__name__} storages: {len(self.locals)}>" + + +class _ProxyLookup: + """Descriptor that handles proxied attribute lookup for + :class:`LocalProxy`. + + :param f: The built-in function this attribute is accessed through. + Instead of looking up the special method, the function call + is redone on the object. + :param fallback: Return this function if the proxy is unbound + instead of raising a :exc:`RuntimeError`. + :param is_attr: This proxied name is an attribute, not a function. + Call the fallback immediately to get the value. + :param class_value: Value to return when accessed from the + ``LocalProxy`` class directly. Used for ``__doc__`` so building + docs still works. + """ + + __slots__ = ("bind_f", "fallback", "is_attr", "class_value", "name") + + def __init__( + self, + f: t.Optional[t.Callable] = None, + fallback: t.Optional[t.Callable] = None, + class_value: t.Optional[t.Any] = None, + is_attr: bool = False, + ) -> None: + bind_f: t.Optional[t.Callable[["LocalProxy", t.Any], t.Callable]] + + if hasattr(f, "__get__"): + # A Python function, can be turned into a bound method. + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + return f.__get__(obj, type(obj)) # type: ignore + + elif f is not None: + # A C function, use partial to bind the first argument. + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + return partial(f, obj) # type: ignore + + else: + # Use getattr, which will produce a bound method. + bind_f = None + + self.bind_f = bind_f + self.fallback = fallback + self.class_value = class_value + self.is_attr = is_attr + + def __set_name__(self, owner: "LocalProxy", name: str) -> None: + self.name = name + + def __get__(self, instance: "LocalProxy", owner: t.Optional[type] = None) -> t.Any: + if instance is None: + if self.class_value is not None: + return self.class_value + + return self + + try: + obj = instance._get_current_object() # type: ignore[misc] + except RuntimeError: + if self.fallback is None: + raise + + fallback = self.fallback.__get__(instance, owner) + + if self.is_attr: + # __class__ and __doc__ are attributes, not methods. + # Call the fallback to get the value. + return fallback() + + return fallback + + if self.bind_f is not None: + return self.bind_f(instance, obj) + + return getattr(obj, self.name) + + def __repr__(self) -> str: + return f"proxy {self.name}" + + def __call__(self, instance: "LocalProxy", *args: t.Any, **kwargs: t.Any) -> t.Any: + """Support calling unbound methods from the class. For example, + this happens with ``copy.copy``, which does + ``type(x).__copy__(x)``. ``type(x)`` can't be proxied, so it + returns the proxy type and descriptor. + """ + return self.__get__(instance, type(instance))(*args, **kwargs) + + +class _ProxyIOp(_ProxyLookup): + """Look up an augmented assignment method on a proxied object. The + method is wrapped to return the proxy instead of the object. + """ + + __slots__ = () + + def __init__( + self, f: t.Optional[t.Callable] = None, fallback: t.Optional[t.Callable] = None + ) -> None: + super().__init__(f, fallback) + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + def i_op(self: t.Any, other: t.Any) -> "LocalProxy": + f(self, other) # type: ignore + return instance + + return i_op.__get__(obj, type(obj)) # type: ignore + + self.bind_f = bind_f + + +def _l_to_r_op(op: F) -> F: + """Swap the argument order to turn an l-op into an r-op.""" + + def r_op(obj: t.Any, other: t.Any) -> t.Any: + return op(other, obj) + + return t.cast(F, r_op) + + +def _identity(o: T) -> T: + return o + + +class LocalProxy(t.Generic[T]): + """A proxy to the object bound to a context-local object. All + operations on the proxy are forwarded to the bound object. If no + object is bound, a ``RuntimeError`` is raised. + + :param local: The context-local object that provides the proxied + object. + :param name: Proxy this attribute from the proxied object. + :param unbound_message: The error message to show if the + context-local object is unbound. + + Proxy a :class:`~contextvars.ContextVar` to make it easier to + access. Pass a name to proxy that attribute. + + .. code-block:: python + + _request_var = ContextVar("request") + request = LocalProxy(_request_var) + session = LocalProxy(_request_var, "session") + + Proxy an attribute on a :class:`Local` namespace by calling the + local with the attribute name: + + .. code-block:: python + + data = Local() + user = data("user") + + Proxy the top item on a :class:`LocalStack` by calling the local. + Pass a name to proxy that attribute. + + .. code-block:: + + app_stack = LocalStack() + current_app = app_stack() + g = app_stack("g") + + Pass a function to proxy the return value from that function. This + was previously used to access attributes of local objects before + that was supported directly. + + .. code-block:: python + + session = LocalProxy(lambda: request.session) + + ``__repr__`` and ``__class__`` are proxied, so ``repr(x)`` and + ``isinstance(x, cls)`` will look like the proxied object. Use + ``issubclass(type(x), LocalProxy)`` to check if an object is a + proxy. + + .. code-block:: python + + repr(user) # + isinstance(user, User) # True + issubclass(type(user), LocalProxy) # True + + .. versionchanged:: 2.2.2 + ``__wrapped__`` is set when wrapping an object, not only when + wrapping a function, to prevent doctest from failing. + + .. versionchanged:: 2.2 + Can proxy a ``ContextVar`` or ``LocalStack`` directly. + + .. versionchanged:: 2.2 + The ``name`` parameter can be used with any proxied object, not + only ``Local``. + + .. versionchanged:: 2.2 + Added the ``unbound_message`` parameter. + + .. versionchanged:: 2.0 + Updated proxied attributes and methods to reflect the current + data model. + + .. versionchanged:: 0.6.1 + The class can be instantiated with a callable. + """ + + __slots__ = ("__wrapped", "_get_current_object") + + _get_current_object: t.Callable[[], T] + """Return the current object this proxy is bound to. If the proxy is + unbound, this raises a ``RuntimeError``. + + This should be used if you need to pass the object to something that + doesn't understand the proxy. It can also be useful for performance + if you are accessing the object multiple times in a function, rather + than going through the proxy multiple times. + """ + + def __init__( + self, + local: t.Union[ContextVar[T], Local, LocalStack[T], t.Callable[[], T]], + name: t.Optional[str] = None, + *, + unbound_message: t.Optional[str] = None, + ) -> None: + if name is None: + get_name = _identity + else: + get_name = attrgetter(name) # type: ignore[assignment] + + if unbound_message is None: + unbound_message = "object is not bound" + + if isinstance(local, Local): + if name is None: + raise TypeError("'name' is required when proxying a 'Local' object.") + + def _get_current_object() -> T: + try: + return get_name(local) # type: ignore[return-value] + except AttributeError: + raise RuntimeError(unbound_message) from None + + elif isinstance(local, LocalStack): + + def _get_current_object() -> T: + obj = local.top # type: ignore[union-attr] + + if obj is None: + raise RuntimeError(unbound_message) + + return get_name(obj) + + elif isinstance(local, ContextVar): + + def _get_current_object() -> T: + try: + obj = local.get() # type: ignore[union-attr] + except LookupError: + raise RuntimeError(unbound_message) from None + + return get_name(obj) + + elif callable(local): + + def _get_current_object() -> T: + return get_name(local()) # type: ignore + + else: + raise TypeError(f"Don't know how to proxy '{type(local)}'.") + + object.__setattr__(self, "_LocalProxy__wrapped", local) + object.__setattr__(self, "_get_current_object", _get_current_object) + + __doc__ = _ProxyLookup( # type: ignore + class_value=__doc__, fallback=lambda self: type(self).__doc__, is_attr=True + ) + __wrapped__ = _ProxyLookup( + fallback=lambda self: self._LocalProxy__wrapped, is_attr=True + ) + # __del__ should only delete the proxy + __repr__ = _ProxyLookup( # type: ignore + repr, fallback=lambda self: f"<{type(self).__name__} unbound>" + ) + __str__ = _ProxyLookup(str) # type: ignore + __bytes__ = _ProxyLookup(bytes) + __format__ = _ProxyLookup() # type: ignore + __lt__ = _ProxyLookup(operator.lt) + __le__ = _ProxyLookup(operator.le) + __eq__ = _ProxyLookup(operator.eq) # type: ignore + __ne__ = _ProxyLookup(operator.ne) # type: ignore + __gt__ = _ProxyLookup(operator.gt) + __ge__ = _ProxyLookup(operator.ge) + __hash__ = _ProxyLookup(hash) # type: ignore + __bool__ = _ProxyLookup(bool, fallback=lambda self: False) + __getattr__ = _ProxyLookup(getattr) + # __getattribute__ triggered through __getattr__ + __setattr__ = _ProxyLookup(setattr) # type: ignore + __delattr__ = _ProxyLookup(delattr) # type: ignore + __dir__ = _ProxyLookup(dir, fallback=lambda self: []) # type: ignore + # __get__ (proxying descriptor not supported) + # __set__ (descriptor) + # __delete__ (descriptor) + # __set_name__ (descriptor) + # __objclass__ (descriptor) + # __slots__ used by proxy itself + # __dict__ (__getattr__) + # __weakref__ (__getattr__) + # __init_subclass__ (proxying metaclass not supported) + # __prepare__ (metaclass) + __class__ = _ProxyLookup( + fallback=lambda self: type(self), is_attr=True + ) # type: ignore + __instancecheck__ = _ProxyLookup(lambda self, other: isinstance(other, self)) + __subclasscheck__ = _ProxyLookup(lambda self, other: issubclass(other, self)) + # __class_getitem__ triggered through __getitem__ + __call__ = _ProxyLookup(lambda self, *args, **kwargs: self(*args, **kwargs)) + __len__ = _ProxyLookup(len) + __length_hint__ = _ProxyLookup(operator.length_hint) + __getitem__ = _ProxyLookup(operator.getitem) + __setitem__ = _ProxyLookup(operator.setitem) + __delitem__ = _ProxyLookup(operator.delitem) + # __missing__ triggered through __getitem__ + __iter__ = _ProxyLookup(iter) + __next__ = _ProxyLookup(next) + __reversed__ = _ProxyLookup(reversed) + __contains__ = _ProxyLookup(operator.contains) + __add__ = _ProxyLookup(operator.add) + __sub__ = _ProxyLookup(operator.sub) + __mul__ = _ProxyLookup(operator.mul) + __matmul__ = _ProxyLookup(operator.matmul) + __truediv__ = _ProxyLookup(operator.truediv) + __floordiv__ = _ProxyLookup(operator.floordiv) + __mod__ = _ProxyLookup(operator.mod) + __divmod__ = _ProxyLookup(divmod) + __pow__ = _ProxyLookup(pow) + __lshift__ = _ProxyLookup(operator.lshift) + __rshift__ = _ProxyLookup(operator.rshift) + __and__ = _ProxyLookup(operator.and_) + __xor__ = _ProxyLookup(operator.xor) + __or__ = _ProxyLookup(operator.or_) + __radd__ = _ProxyLookup(_l_to_r_op(operator.add)) + __rsub__ = _ProxyLookup(_l_to_r_op(operator.sub)) + __rmul__ = _ProxyLookup(_l_to_r_op(operator.mul)) + __rmatmul__ = _ProxyLookup(_l_to_r_op(operator.matmul)) + __rtruediv__ = _ProxyLookup(_l_to_r_op(operator.truediv)) + __rfloordiv__ = _ProxyLookup(_l_to_r_op(operator.floordiv)) + __rmod__ = _ProxyLookup(_l_to_r_op(operator.mod)) + __rdivmod__ = _ProxyLookup(_l_to_r_op(divmod)) + __rpow__ = _ProxyLookup(_l_to_r_op(pow)) + __rlshift__ = _ProxyLookup(_l_to_r_op(operator.lshift)) + __rrshift__ = _ProxyLookup(_l_to_r_op(operator.rshift)) + __rand__ = _ProxyLookup(_l_to_r_op(operator.and_)) + __rxor__ = _ProxyLookup(_l_to_r_op(operator.xor)) + __ror__ = _ProxyLookup(_l_to_r_op(operator.or_)) + __iadd__ = _ProxyIOp(operator.iadd) + __isub__ = _ProxyIOp(operator.isub) + __imul__ = _ProxyIOp(operator.imul) + __imatmul__ = _ProxyIOp(operator.imatmul) + __itruediv__ = _ProxyIOp(operator.itruediv) + __ifloordiv__ = _ProxyIOp(operator.ifloordiv) + __imod__ = _ProxyIOp(operator.imod) + __ipow__ = _ProxyIOp(operator.ipow) + __ilshift__ = _ProxyIOp(operator.ilshift) + __irshift__ = _ProxyIOp(operator.irshift) + __iand__ = _ProxyIOp(operator.iand) + __ixor__ = _ProxyIOp(operator.ixor) + __ior__ = _ProxyIOp(operator.ior) + __neg__ = _ProxyLookup(operator.neg) + __pos__ = _ProxyLookup(operator.pos) + __abs__ = _ProxyLookup(abs) + __invert__ = _ProxyLookup(operator.invert) + __complex__ = _ProxyLookup(complex) + __int__ = _ProxyLookup(int) + __float__ = _ProxyLookup(float) + __index__ = _ProxyLookup(operator.index) + __round__ = _ProxyLookup(round) + __trunc__ = _ProxyLookup(math.trunc) + __floor__ = _ProxyLookup(math.floor) + __ceil__ = _ProxyLookup(math.ceil) + __enter__ = _ProxyLookup() + __exit__ = _ProxyLookup() + __await__ = _ProxyLookup() + __aiter__ = _ProxyLookup() + __anext__ = _ProxyLookup() + __aenter__ = _ProxyLookup() + __aexit__ = _ProxyLookup() + __copy__ = _ProxyLookup(copy.copy) + __deepcopy__ = _ProxyLookup(copy.deepcopy) + # __getnewargs_ex__ (pickle through proxy not supported) + # __getnewargs__ (pickle) + # __getstate__ (pickle) + # __setstate__ (pickle) + # __reduce__ (pickle) + # __reduce_ex__ (pickle) diff --git a/lib/python3.10/site-packages/werkzeug/middleware/__init__.py b/lib/python3.10/site-packages/werkzeug/middleware/__init__.py new file mode 100644 index 0000000..6ddcf7f --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/__init__.py @@ -0,0 +1,22 @@ +""" +Middleware +========== + +A WSGI middleware is a WSGI application that wraps another application +in order to observe or change its behavior. Werkzeug provides some +middleware for common use cases. + +.. toctree:: + :maxdepth: 1 + + proxy_fix + shared_data + dispatcher + http_proxy + lint + profiler + +The :doc:`interactive debugger ` is also a middleware that can +be applied manually, although it is typically used automatically with +the :doc:`development server `. +""" diff --git a/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee6d249aae4b197cec545f5280fd3b11696cfa4c GIT binary patch literal 703 zcmYjPO^XyU5bfEELtrodg1Rnfw~M!C9TWudpa`ohc*)cxHQjO2Nl4Q3;Xm@|&)L0t z_U6fx)tO`FdOe6_n2W9F)-_V?kU0tj+#lrH>`Rq;9#>0^8B48A3YZm(FJ+%|kfo!P*0@{} zhStXNCh@r^Xth`Ek~xZ~vf;rrt;Vk7VQ-p}E|$eKn>;&rHb(JGp%W`QnnfB0bR$}O zcm`;5@5ioZcc%7y2<$a8)5scd%zj|&kI>HKUa;vWF`BkyeHh4PC|*xero^~zv8=_% ztJ%X7DOtFbKdN}a&!H@T*UcB+mKsamHE$_xvJXu-un;FdMgNUdPR-h4+BDXzPRz^t t`bCpWrso0G20Kd4?(_?r|I;>78fUVUbvQiCZw9YNON;4Ars@89^$%5n;`smo literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc b/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23b8da435c39504d77051ca331042964bf0b18dc GIT binary patch literal 2787 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 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/lint.cpython-310.pyc b/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/lint.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c04e467f6a6f74ec7f8261af7211551d4b23c373 GIT binary patch literal 12751 zcma)C&2t>bb)T=Dot<4QJ_v#!MM)#cHn|qLphWo#p=Ht(B+{lpnuNq?%gJi6GXNIY z53qZd5Vn?y%8)H7i5*vRbnK9oT$o#~`3rK$DYwiqIiy&Xn@^!cGQanFW@i@!tt@I9 zJw4qs-LK!r@4eUEi3wN3??3)|rt#}M1CHqCD+qCQib;d%-6L$yP?_Kp@z1m#b(pd8NbnYF{XpA4pOKgIWR;gK~xm=2Ew zGvR!22=6@_%m&7q6C4iaKFQUNq5qL!9{uO{jM{U!I~p9r-7(x9$K7+maoiop-SfD6 zK6n9lFW~M4+`SlhxbtxLVqo0RDlhqe339kMZ@hEayC%9(x6y5RSDKwD6z=yA__^-N zMpJt2ZqRFm-nQu8ZU&+Be6QUMf>yZWi_nWU{K(r5#adUir6>JPGurhU8)0Khdfg5l zhwf^);ooj{h1Xr9dyl^_LvcG4p5F;Pe|x*tZ1_>L+o^h&qjWUCnZ_?}hue!Ep2hFO zWbAg>@GvpV2w!gPdd>EBD{O~YNWgFKTe9n6dL5pF?6yO<(QUUepGzw%*St`OuE1n_ zjSbJ2UZ>kR9k#bIZxPDvZbxE`SdMr0%p0DJ{HQ0rMi&dOx^A`V`909B4TJ&B&bLKnVHNVvgBk3+;fgxVJ=>71^1wh>+~hBXeh>QqzKv1SmwzQK)XE56-q zg*OFA8VcM_+=zS;T~C&UhDjp+g^b{7(^BVlQ*=8-!v;-i^aq|{Vfy_PDxp@>Ay5#c zn#oLM#zlJPP0X>`S?_yE#bX*V9eKZL4R|iA%lEC=snO@R;FsR)Ha9WWvU!b@8W!;3*P=Hip}ooW^8rBFoo<1;ox;P%`1MN51w}G)~;J=}saozl_9hrd@tOg)|oe6tiUk35= zbv5?B5nD2Bt%;Y>X+L=&C{1Y8di@N&hTiAu{n?QjRMQTz<%@OMAX!a+)IEpm9bEE< zDAbMz`j#Qe5e#AkDg_qpd1oSdmfJGLb9iQF&j#8is5;Pp1-_`{mj!*I|Mx7^K^KhC z0aL8^eBpydLnw4_>FV2F+ZS6<@5%yrO(Gd|Dbef{YydQB+uwpZ@ETB%(u=y@i5uXMW@)Y(d_OU;v}`aO2s%! ziz?dA;*!J^#LM_I4c+;ol;=9`?MJ0te`<6a>7~!!yeoLqAK1K^;pQ16=A)a}u^`y_ zJ^g3kzD;X0mu#bxY-9c6v*-_P7}6f>G@)FvdEl-dSqGSZSp9Topp6gQxn@U3SkcHf zh*MZY|IhYs^YAmU!?bbO4*H_!d$QRNy$#aI%IFVyP4>38yCUMvKIQo>n&0|{*NjeJ zZnynr%U=ar0q5a$*z!$S@`P)u{cjD~AY0F~xgeQbwPK6Yn0>|xae>VA62SS&zjxfLxUzTj<2(CN%(mv5n-#Nw?#LW&a(kl|sSL@r@eQgtJ z{w4&}(jsH`n6A+uc3zJxQiUYqkrr5cx~+YHUOQSPx7>ezWHU|>o+3$xnG{68(XFH9 zKpHH1#_JWNjxuuG*OfGkFPp49ji}de(pmCeQK>F$E-t%c36W> zic75st2XYM_pnkjSru!!e{u!zas*BSgmhWL(LAbyUdq(NeJfjs+RGdd5+uU=H}X4Z z`%_#D4a!(Ze|l7ic_35+TZ77kGJ^z~#59Unk7DEU)i}4h8--F-sL8z0*=2)VRG7C zJ>_ktOvOk(zt-x>jRX1fEsWg4CFxznougmnVOU0ZYm7!Fx(;bXIBlT6rTt0%jxo^g zY6F9)bITwBQg@5pO{%@<3X#aM8o>q8O)?QUKqhua@=+u~?)be?-LvDoBc%B7$h2 z2r$&AAkg(}0saA=HgF9Ec*bEmq(J1r}EeLh8n)cYxZ0Ft|yK&Wnic#zwERB@;YLtdahxKIBl+ zX$sE{z$SG#geiL%v0dja1-@19N?C>2M*N71aZX_peuQ=w7F!3vJv=(Gp>T`y=rqQ< zG@l{sl2#!5kcszQLkTxz$-HYtz&?9p!k*`eLc(p9a6t}}_%RiPw_=-|=uV(a|3zvZ zpE%h!f-Lp=01uhLOPKxa)ALuoD#e3%DRu~gk;Ucj$2L4Xc(Ji{r77X>0skl-TOOYP zPlav4WjxqPC*Wu&^*KvW8?o2ek5I#TTyg`&ekMxT#}2_j%uFV0`aIgoSZKZzwZC zo0|TpK4d&nI*Re&&0;$@iTwa`P+H82xq*qg&49pIe!G&73k*WosJ@QT9D9H(jd(+@ z-XWjbRvoZQF>Ii8^#||Gp3^ZonL#FuQ6L zj@iTp?7oqZ{?xdm-!Y)Iv`u?Yzhfe7lMl?ufx~Xxfjb`L;Ksi@Fkq~Y zqHpewJ;>cHU=wo#DE`~JxDdI6+#dZe2Khk_As^?rW>nfUV9-wvOz~s17t}q83t#R) zw=`4R(#6f7xTVRTc3}STtrEU(NF<7cYW@%`+ff#fbCaN81#T z>Q4>3bye`VUtZ#9sHe1w*FS>rV-Er5W`|?B86&+yq22Tr!GxZS*!e-68vcW~+6{KA z4+4Dj!M{@RZzxpQo!WA(F5;kq_*2OZMIKeyF0Uk`sKVcM3V-9(@Np3~skuBQ=B^0(^GF;up<+6B{bO$v9_|Py3B^n=FW*PrqFdVef zWj(g6S+q@S0vOR+eWJ;5BeMc!l;>MfIkMN$& z-NVXz{(xI{xU9f6cq9D)5)0B>_r)qA$w&+!X3-#3l_@WJt~6j3res_##f7Dh8sRqO zIu1gmKuz@^1f(FolQSr6RyvmMJ}H@~Ke4{(A9>os@EGVbGN0lG6^vdd4?-M*$gjXg zZl#CB33G!Wj46IX1!Gz=HiFckVxlJ1GW?Ul5Bk{8aLMB+9C-MSVLUFG#v{ivzBF>~ z7jCI+y3^&a^Ryc1H1;Foc^;Si7Ze#NL2lt#0y!+CxD?391*OmqCc^xtgR2nQ3ikq{ zlyUEJTYj?`mX2y+DV$g{k7@*8xV;=s608A`q2!xYo5Fi08QNF?EHh}CM)EDcITIdA zAdiJK++noO26JdX930`2-o|}^ujhlKcs|E4=XhMc0<4xLgZ#gP;iYr{f>Ns#KuZ!( z?59XlNhIbRMWq}VX9xBr%3Ke>kv!QBr*(qS07uokf#g=2SZhkzLqHbxGfBW9RJZ8z zYfj@;%?`w}8I0w$h7TzT_Oz}L}I@bWTId*rz0sS7PgxaO{pg-{!E*;h>X?ZhiNM3!z4e7>>%yeBFC3$j~2a^ z;SOgsAtg>5nRG`&k(BG{)mFE$g^Z%gWvN%u>zKA_wyK(CtE%v<5v*%-By^nfcp5Yo zbMU^uFGqP2jTP<@o2Uwszpuz%WU(1o;uiWRxQXi{I)S|r(j5=zo!>;!KQcbEAryuY zSNTR!M7J@Yj*t?mBG%QU1yyW2(t#o-07`X4H51SpSinBh2voq&1K#oQG&i8smJOVP zsJDs|-kJn{A*Z+i{82?8H+weF?^=}Txn}@hQGJ5zz$)U(zzoV5HHlGIFluUG{>A{h z8NPR5i4TEp(mt!`Gd-}z`=r>0{#Ry}`wJ{j$=WHJoq|d*Z|TNL{oSRNOIP2j6>ltEe}CzEefh$>OT(LMSFf);EHTdmh)W3C zLpPIvhs7+u1pvi2?OqEhG^A61`5n+i8UTqt{hF5F(moj6E2A z54l1@H;lLh83VD60=#mH>STiZFDF^%Y}HJU*Q#gIw^gx_i`Oq-Tj5p3TCH&H!pf!k z<>j}p@+%(d3;kD5jC45x7?k9o*k>4K50C@iSoHdp6T=sLMb}D>VP+~;A30C@$M=cV*heTQNoN)W;n&y+KWgyI8pKNJ zuYk%>$lk}^j0H~gyNLG%#yyDHQSA;ANCPAe0&B~Z^8@Rybx)Hol1~`fu%9-k79c$6 zk%z3!^`z{LI{rMJt{!luj9!?_Jm!X z@7=K@X8?yNa(lX5#oSO2%J^Cny(dR{+i;5VcO3La`is-!0yQ zV+J?pmv}OrJ-M|4ML;gh@1oMcjNCm#{ti86vL4X{&6wk*Wfdm1L?XjqMbFIu|ay0(}!fHFXEJw#7UuQ|GB5>mx@KTGATUTq6;YE zoWx0_h=T)hp(%r~(QNyz5oJJrQ=%ql)p3s3Bvxs#+XOC!b57Ck3S2@GR0ar2VDw@l2k2xVZYS9H?lJEgYBd|HR2YePS7(SXg>#BSEB-l>S!&f zR*p~@;`PAYGUOsfC@{V_GM>I!!Z*!Cbbk`Tq9a(ClQ+`oYASQ^b_miswP>vJl`4VCy9ZOgJRM{`7GU`qR z0@?tF01&A_V6p>meFKL-pvrLW5GNYEs0rU`EU0qI+u3O1R3H!AqOsUqb_XEURqwhw zYvL;fh;3m9f{q&u4?HmPp>rpo`=8^V3OtfrsK`okaOAJ3VSEn|OQB@5T^ z>otUx)SUqCP8Z;Ocxt4|a8w!gTcD*7C=&de!9zT2|h*X^7!lR75<97AFrSeIf062*O zwet8pl<+Y~Kf-bc?;iGd)SCVU2_Q{@>|;5B;+9R?(b4BjBZoozt-hH~=6x7J{?J6b>>tmStD~6u6$y zRW@cH&(4vCnn!5%0Ea)xeOfA7kcAtd9(ghp08jyl%8~uiN{WA~Xe1Nm0^KfB!C^{T zYwTR*SgPNOEjp4FPy7&uI18~dClBeNIOk(}!zC)1j!ZnJEiHdUC$o0upvD#+{5vlB zH5879VCjFc;4pfDyBl zg60*MaK;;_l&gHsTd>V`(x?&}^IAFZBii6z1EDqyqfL#ijVRjYsC~^M=bTvtC&)jz zwp71(Y3bsRFE77SEAx?BxdGJ9eTdgou!jg9=P5EtlbWD*j{7rpDL*LwmI{xGj14c- zEwdOc?I0?}&N+3G`%Q3=CW-MZ%_-A?FZ{uwMTV41xVGk$EtVEeh zZf0gJue>_hfR#hqKOiX}9dqoTQ(klGxtAtQlm6atS6bN$kVCoP<8VISypP{|^SJrk zTwvk)$KRLZ*Uwqj*Yq-d`FOdCTYU+_t+vH&?xc3xG0#f7VxDf>HP33>!?TjsdVbrt ztvw%aZaUKo+JSA|x3UG-60^fq+oGQttCwS+Sed5WQntR&cG~Pm?&(NuII0GVdm-kimOrTtRSe zJ5j8c^FbKz(ino~*pALl5Y&X%{7#Bec99o@t zyjN$;u*nSfILg?zNc#-DGo5sYY%|w76`6=1D3)Ywm=7e2b1nk2S1-a0!Bm>>CfOF_ z`R;g1bfQ)>2%1e64Rju-ky5SJv7Wb&B@cpDocD(^+1l1E_M6L>f5+}dX)3e|S}>2u zlxVR(Y}~l?_ND7-G*BY=C;V%zH|(Oip(Cx(sEt)Za}Iq{eVWn*GEeJ$YSDsJ@@L|APbZ~~0l72)nwxx*{m<<)MLd%VVdK%pl53ve)6 zGo}@ombViKU(AYnw{pS4_$-0OjMs(F=eXOQ=kt8wX|+Ai7x@xj=I8jFS-Eh*>Uw;I zpMUDM7r6__yi_cYb(ANji_X<7>%NTofC6dBrcBSGj8E`D&S&D0hzAC1dDq}0V7SH@ zX|jpM04tzrbI|PyDL7Mki7cJ;;N^0#mt%%_6vZ0;B__AJtkY3iim2D=Fd%g+c_^}r ztW|ow(^urDrtwzC@ZXh*)*@p%XNfjEqOKP56mFX(-!Y~`p2*Y8PlMSo;gOD583Ck) ziXK7*>|p>41|rtE9A0F3Cd@R}$DR`tl)Bu5sfa@s^#r4s0LJ5i(s?i01GCK`>jTMz z_)cdsFYM;B7wJxiL^gsXn#>R}7zI-=LP zw{D(}L#&&Kl!NQTC`qHuRJ2NoFTn$y&SPSe^L^Op5&~LG)M91-yX@xLy^HMboefZ- zNVzdxmTUMwQSd*xf6PUsQD2EE3C0}^*bxk% zBW;e2J++X=PqsgEw%G?To7go*h9DE1vMhDNtdn$ChD4_$%0TaQ3=^Kj+Qi0KA1U-e zW^mQSnPW`1`jL!!6j3c>&KKefu-ZlFl_nU^E@Pm@?gQR{AECa4AHYzKHQ9|sk>sVA zoz6P22;dmmCR}osHwm;;R<^lhwCZZ zOuRG>xfc7tgdSO!ViFPbB2PxKtS%l~33DQZc8MS$k^n%9BQw!h6!7k+QC6PK(PsWo zjA4P}jE=xdn`s_Dzd-5Xl2wnfKVPkPr66V5@m@J~zj@OP2Kd9tx@8yLdawwgiVLmz!_>_LzsswWm_8KuTr_W$Gz6oXV(lVw4&0 zm<=C;^;Fs`k^J5Sxn}Z-KoRFJigS%R&&-(5>vOXFont8`tEZ6($w}Vlv?;ODa0-{w zNV`g2R$p1`d#jWD*nDiVUGwocJGGjZyZb%Wd`t_>i*Z#^fw5&3$A96K`W7`4Nt?r> zJ}pNvJ7vyd;W>O3UJ0)l2leqqZ3p*t-0Dq`kv+0PYvh31qY9`qazQJjDyTd1K&#x^ zu)ea_8(!gt5Ur>ors=>f{BR=ITzE>bdN?iFV)&eBjauOPd90jwO}N{tyahy=cKHkJz1Of8sWMduH76^I+Bn%u z56g;q}xn1+w@O0)gi=TgHJ+skQ z>AF<+J+1FowDrW=ceQJFt1}f(43N@(`a4NA}?ipW(rg)4$DUM>Sqwu}ZFd z?sIqF*TK##b_4H`f8^}@kfM$jq(I-C+3!m|KXT36{O8X8%xGq30dI?c!6%Jg;?$nw zi=R7KVIMBzGi3>U0*ow=f-juEIVa;-c@A$Yla*gs{M@N=Z_B1Cb^Vli$*g2^e63k( z8RP&!2iTn_6>Mqk0Mc>^-6+XDU|M9nQK4{)^gtE0Z4q(ct?MZR258 z59QCWxJ2j$w2GJUF%@qkmD71Q<@ikuDiWj)80}p-6F`(H!mxP-c|A(i`^_I=B^SXa z#(jJNH5Ns*QS$d_z_U;ko&tgntRn|DwGNy^#5MUwBeJ>k#F4L#ti$RNeO$r}bT=yN z2BAeYPIG*^c#=$3*t&4zNa?~8k5Dpm7$#DY)>6KX;fCGzVY(0zCL6B&CA#EmM1Dc! z6(S~rjeR^h$S}E!UPTe^+I8FgA*cinJ@}KIo?YKpAt*d{%+Hec6EJq8MvM|E6tQjSJyEkl;h4$`V z`afTQmrEI=u=YF>u*C{HD1qk~f37#qOTwxVqg{iBgoeW1$&*aJgn`1R4l3K^%k=7% zm3mR7vIDtT3RDZRD4bl$RZM6He9-HcRhJ}SNXqx^;G`ClE5xU2N~NN*C3G9-$Z^>u z&ttSPTl&wq(;%JBilR2om9#lPUbrR_F4K@dN%3Y(tM&|8*~E@PL8E#mKn!mK5TxER z4*m>wioonv7M&H>oAK=czq%bbL_No|Unx`acZ(iIoO$%py<%?9`H?hTa&IhAlBcRH z42vKP%Re^Iu7}~LgD4%3)WVSGF}f>is3xHL>eIzQQP1`FA_7WuiH~6bG}W#y6rfNpo>t+tJKk|+sl>z E0S1DeUH||9 literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc b/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8247d874bdf38c63c700077c0c1cb9d726fb45cd GIT binary patch literal 6205 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 brP(DL4v7BvpeHSX&*7hAT-5W~^R)Rt-OZwg literal 0 HcmV?d00001 diff --git a/lib/python3.10/site-packages/werkzeug/middleware/dispatcher.py b/lib/python3.10/site-packages/werkzeug/middleware/dispatcher.py new file mode 100644 index 0000000..ace1c75 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/dispatcher.py @@ -0,0 +1,78 @@ +""" +Application Dispatcher +====================== + +This middleware creates a single WSGI application that dispatches to +multiple other WSGI applications mounted at different URL paths. + +A common example is writing a Single Page Application, where you have a +backend API and a frontend written in JavaScript that does the routing +in the browser rather than requesting different pages from the server. +The frontend is a single HTML and JS file that should be served for any +path besides "/api". + +This example dispatches to an API app under "/api", an admin app +under "/admin", and an app that serves frontend files for all other +requests:: + + app = DispatcherMiddleware(serve_frontend, { + '/api': api_app, + '/admin': admin_app, + }) + +In production, you might instead handle this at the HTTP server level, +serving files or proxying to application servers based on location. The +API and admin apps would each be deployed with a separate WSGI server, +and the static files would be served directly by the HTTP server. + +.. autoclass:: DispatcherMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class DispatcherMiddleware: + """Combine multiple applications as a single WSGI application. + Requests are dispatched to an application based on the path it is + mounted under. + + :param app: The WSGI application to dispatch to if the request + doesn't match a mounted path. + :param mounts: Maps path prefixes to applications for dispatching. + """ + + def __init__( + self, + app: "WSGIApplication", + mounts: t.Optional[t.Dict[str, "WSGIApplication"]] = None, + ) -> None: + self.app = app + self.mounts = mounts or {} + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + script = environ.get("PATH_INFO", "") + path_info = "" + + while "/" in script: + if script in self.mounts: + app = self.mounts[script] + break + + script, last_item = script.rsplit("/", 1) + path_info = f"/{last_item}{path_info}" + else: + app = self.mounts.get(script, self.app) + + original_script_name = environ.get("SCRIPT_NAME", "") + environ["SCRIPT_NAME"] = original_script_name + script + environ["PATH_INFO"] = path_info + return app(environ, start_response) diff --git a/lib/python3.10/site-packages/werkzeug/middleware/http_proxy.py b/lib/python3.10/site-packages/werkzeug/middleware/http_proxy.py new file mode 100644 index 0000000..1cde458 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/http_proxy.py @@ -0,0 +1,230 @@ +""" +Basic HTTP Proxy +================ + +.. autoclass:: ProxyMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t +from http import client + +from ..datastructures import EnvironHeaders +from ..http import is_hop_by_hop_header +from ..urls import url_parse +from ..urls import url_quote +from ..wsgi import get_input_stream + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class ProxyMiddleware: + """Proxy requests under a path to an external server, routing other + requests to the app. + + This middleware can only proxy HTTP requests, as HTTP is the only + protocol handled by the WSGI server. Other protocols, such as + WebSocket requests, cannot be proxied at this layer. This should + only be used for development, in production a real proxy server + should be used. + + The middleware takes a dict mapping a path prefix to a dict + describing the host to be proxied to:: + + app = ProxyMiddleware(app, { + "/static/": { + "target": "http://127.0.0.1:5001/", + } + }) + + Each host has the following options: + + ``target``: + The target URL to dispatch to. This is required. + ``remove_prefix``: + Whether to remove the prefix from the URL before dispatching it + to the target. The default is ``False``. + ``host``: + ``""`` (default): + The host header is automatically rewritten to the URL of the + target. + ``None``: + The host header is unmodified from the client request. + Any other value: + The host header is overwritten with the value. + ``headers``: + A dictionary of headers to be sent with the request to the + target. The default is ``{}``. + ``ssl_context``: + A :class:`ssl.SSLContext` defining how to verify requests if the + target is HTTPS. The default is ``None``. + + In the example above, everything under ``"/static/"`` is proxied to + the server on port 5001. The host header is rewritten to the target, + and the ``"/static/"`` prefix is removed from the URLs. + + :param app: The WSGI application to wrap. + :param targets: Proxy target configurations. See description above. + :param chunk_size: Size of chunks to read from input stream and + write to target. + :param timeout: Seconds before an operation to a target fails. + + .. versionadded:: 0.14 + """ + + def __init__( + self, + app: "WSGIApplication", + targets: t.Mapping[str, t.Dict[str, t.Any]], + chunk_size: int = 2 << 13, + timeout: int = 10, + ) -> None: + def _set_defaults(opts: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: + opts.setdefault("remove_prefix", False) + opts.setdefault("host", "") + opts.setdefault("headers", {}) + opts.setdefault("ssl_context", None) + return opts + + self.app = app + self.targets = { + f"/{k.strip('/')}/": _set_defaults(v) for k, v in targets.items() + } + self.chunk_size = chunk_size + self.timeout = timeout + + def proxy_to( + self, opts: t.Dict[str, t.Any], path: str, prefix: str + ) -> "WSGIApplication": + target = url_parse(opts["target"]) + host = t.cast(str, target.ascii_host) + + def application( + environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + headers = list(EnvironHeaders(environ).items()) + headers[:] = [ + (k, v) + for k, v in headers + if not is_hop_by_hop_header(k) + and k.lower() not in ("content-length", "host") + ] + headers.append(("Connection", "close")) + + if opts["host"] == "": + headers.append(("Host", host)) + elif opts["host"] is None: + headers.append(("Host", environ["HTTP_HOST"])) + else: + headers.append(("Host", opts["host"])) + + headers.extend(opts["headers"].items()) + remote_path = path + + if opts["remove_prefix"]: + remote_path = remote_path[len(prefix) :].lstrip("/") + remote_path = f"{target.path.rstrip('/')}/{remote_path}" + + content_length = environ.get("CONTENT_LENGTH") + chunked = False + + if content_length not in ("", None): + headers.append(("Content-Length", content_length)) # type: ignore + elif content_length is not None: + headers.append(("Transfer-Encoding", "chunked")) + chunked = True + + try: + if target.scheme == "http": + con = client.HTTPConnection( + host, target.port or 80, timeout=self.timeout + ) + elif target.scheme == "https": + con = client.HTTPSConnection( + host, + target.port or 443, + timeout=self.timeout, + context=opts["ssl_context"], + ) + else: + raise RuntimeError( + "Target scheme must be 'http' or 'https', got" + f" {target.scheme!r}." + ) + + con.connect() + remote_url = url_quote(remote_path) + querystring = environ["QUERY_STRING"] + + if querystring: + remote_url = f"{remote_url}?{querystring}" + + con.putrequest(environ["REQUEST_METHOD"], remote_url, skip_host=True) + + for k, v in headers: + if k.lower() == "connection": + v = "close" + + con.putheader(k, v) + + con.endheaders() + stream = get_input_stream(environ) + + while True: + data = stream.read(self.chunk_size) + + if not data: + break + + if chunked: + con.send(b"%x\r\n%s\r\n" % (len(data), data)) + else: + con.send(data) + + resp = con.getresponse() + except OSError: + from ..exceptions import BadGateway + + return BadGateway()(environ, start_response) + + start_response( + f"{resp.status} {resp.reason}", + [ + (k.title(), v) + for k, v in resp.getheaders() + if not is_hop_by_hop_header(k) + ], + ) + + def read() -> t.Iterator[bytes]: + while True: + try: + data = resp.read(self.chunk_size) + except OSError: + break + + if not data: + break + + yield data + + return read() + + return application + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + path = environ["PATH_INFO"] + app = self.app + + for prefix, opts in self.targets.items(): + if path.startswith(prefix): + app = self.proxy_to(opts, path, prefix) + break + + return app(environ, start_response) diff --git a/lib/python3.10/site-packages/werkzeug/middleware/lint.py b/lib/python3.10/site-packages/werkzeug/middleware/lint.py new file mode 100644 index 0000000..6b54630 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/lint.py @@ -0,0 +1,420 @@ +""" +WSGI Protocol Linter +==================== + +This module provides a middleware that performs sanity checks on the +behavior of the WSGI server and application. It checks that the +:pep:`3333` WSGI spec is properly implemented. It also warns on some +common HTTP errors such as non-empty responses for 304 status codes. + +.. autoclass:: LintMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t +from types import TracebackType +from urllib.parse import urlparse +from warnings import warn + +from ..datastructures import Headers +from ..http import is_entity_header +from ..wsgi import FileWrapper + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class WSGIWarning(Warning): + """Warning class for WSGI warnings.""" + + +class HTTPWarning(Warning): + """Warning class for HTTP warnings.""" + + +def check_type(context: str, obj: object, need: t.Type = str) -> None: + if type(obj) is not need: + warn( + f"{context!r} requires {need.__name__!r}, got {type(obj).__name__!r}.", + WSGIWarning, + stacklevel=3, + ) + + +class InputStream: + def __init__(self, stream: t.IO[bytes]) -> None: + self._stream = stream + + def read(self, *args: t.Any) -> bytes: + if len(args) == 0: + warn( + "WSGI does not guarantee an EOF marker on the input stream, thus making" + " calls to 'wsgi.input.read()' unsafe. Conforming servers may never" + " return from this call.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) != 1: + warn( + "Too many parameters passed to 'wsgi.input.read()'.", + WSGIWarning, + stacklevel=2, + ) + return self._stream.read(*args) + + def readline(self, *args: t.Any) -> bytes: + if len(args) == 0: + warn( + "Calls to 'wsgi.input.readline()' without arguments are unsafe. Use" + " 'wsgi.input.read()' instead.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) == 1: + warn( + "'wsgi.input.readline()' was called with a size hint. WSGI does not" + " support this, although it's available on all major servers.", + WSGIWarning, + stacklevel=2, + ) + else: + raise TypeError("Too many arguments passed to 'wsgi.input.readline()'.") + return self._stream.readline(*args) + + def __iter__(self) -> t.Iterator[bytes]: + try: + return iter(self._stream) + except TypeError: + warn("'wsgi.input' is not iterable.", WSGIWarning, stacklevel=2) + return iter(()) + + def close(self) -> None: + warn("The application closed the input stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class ErrorStream: + def __init__(self, stream: t.IO[str]) -> None: + self._stream = stream + + def write(self, s: str) -> None: + check_type("wsgi.error.write()", s, str) + self._stream.write(s) + + def flush(self) -> None: + self._stream.flush() + + def writelines(self, seq: t.Iterable[str]) -> None: + for line in seq: + self.write(line) + + def close(self) -> None: + warn("The application closed the error stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class GuardedWrite: + def __init__(self, write: t.Callable[[bytes], object], chunks: t.List[int]) -> None: + self._write = write + self._chunks = chunks + + def __call__(self, s: bytes) -> None: + check_type("write()", s, bytes) + self._write(s) + self._chunks.append(len(s)) + + +class GuardedIterator: + def __init__( + self, + iterator: t.Iterable[bytes], + headers_set: t.Tuple[int, Headers], + chunks: t.List[int], + ) -> None: + self._iterator = iterator + self._next = iter(iterator).__next__ + self.closed = False + self.headers_set = headers_set + self.chunks = chunks + + def __iter__(self) -> "GuardedIterator": + return self + + def __next__(self) -> bytes: + if self.closed: + warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2) + + rv = self._next() + + if not self.headers_set: + warn( + "The application returned before it started the response.", + WSGIWarning, + stacklevel=2, + ) + + check_type("application iterator items", rv, bytes) + self.chunks.append(len(rv)) + return rv + + def close(self) -> None: + self.closed = True + + if hasattr(self._iterator, "close"): + self._iterator.close() # type: ignore + + if self.headers_set: + status_code, headers = self.headers_set + bytes_sent = sum(self.chunks) + content_length = headers.get("content-length", type=int) + + if status_code == 304: + for key, _value in headers: + key = key.lower() + if key not in ("expires", "content-location") and is_entity_header( + key + ): + warn( + f"Entity header {key!r} found in 304 response.", HTTPWarning + ) + if bytes_sent: + warn("304 responses must not have a body.", HTTPWarning) + elif 100 <= status_code < 200 or status_code == 204: + if content_length != 0: + warn( + f"{status_code} responses must have an empty content length.", + HTTPWarning, + ) + if bytes_sent: + warn(f"{status_code} responses must not have a body.", HTTPWarning) + elif content_length is not None and content_length != bytes_sent: + warn( + "Content-Length and the number of bytes sent to the" + " client do not match.", + WSGIWarning, + ) + + def __del__(self) -> None: + if not self.closed: + try: + warn( + "Iterator was garbage collected before it was closed.", WSGIWarning + ) + except Exception: + pass + + +class LintMiddleware: + """Warns about common errors in the WSGI and HTTP behavior of the + server and wrapped application. Some of the issues it checks are: + + - invalid status codes + - non-bytes sent to the WSGI server + - strings returned from the WSGI application + - non-empty conditional responses + - unquoted etags + - relative URLs in the Location header + - unsafe calls to wsgi.input + - unclosed iterators + + Error information is emitted using the :mod:`warnings` module. + + :param app: The WSGI application to wrap. + + .. code-block:: python + + from werkzeug.middleware.lint import LintMiddleware + app = LintMiddleware(app) + """ + + def __init__(self, app: "WSGIApplication") -> None: + self.app = app + + def check_environ(self, environ: "WSGIEnvironment") -> None: + if type(environ) is not dict: + warn( + "WSGI environment is not a standard Python dict.", + WSGIWarning, + stacklevel=4, + ) + for key in ( + "REQUEST_METHOD", + "SERVER_NAME", + "SERVER_PORT", + "wsgi.version", + "wsgi.input", + "wsgi.errors", + "wsgi.multithread", + "wsgi.multiprocess", + "wsgi.run_once", + ): + if key not in environ: + warn( + f"Required environment key {key!r} not found", + WSGIWarning, + stacklevel=3, + ) + if environ["wsgi.version"] != (1, 0): + warn("Environ is not a WSGI 1.0 environ.", WSGIWarning, stacklevel=3) + + script_name = environ.get("SCRIPT_NAME", "") + path_info = environ.get("PATH_INFO", "") + + if script_name and script_name[0] != "/": + warn( + f"'SCRIPT_NAME' does not start with a slash: {script_name!r}", + WSGIWarning, + stacklevel=3, + ) + + if path_info and path_info[0] != "/": + warn( + f"'PATH_INFO' does not start with a slash: {path_info!r}", + WSGIWarning, + stacklevel=3, + ) + + def check_start_response( + self, + status: str, + headers: t.List[t.Tuple[str, str]], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ], + ) -> t.Tuple[int, Headers]: + check_type("status", status, str) + status_code_str = status.split(None, 1)[0] + + if len(status_code_str) != 3 or not status_code_str.isdecimal(): + warn("Status code must be three digits.", WSGIWarning, stacklevel=3) + + if len(status) < 4 or status[3] != " ": + warn( + f"Invalid value for status {status!r}. Valid status strings are three" + " digits, a space and a status explanation.", + WSGIWarning, + stacklevel=3, + ) + + status_code = int(status_code_str) + + if status_code < 100: + warn("Status code < 100 detected.", WSGIWarning, stacklevel=3) + + if type(headers) is not list: + warn("Header list is not a list.", WSGIWarning, stacklevel=3) + + for item in headers: + if type(item) is not tuple or len(item) != 2: + warn("Header items must be 2-item tuples.", WSGIWarning, stacklevel=3) + name, value = item + if type(name) is not str or type(value) is not str: + warn( + "Header keys and values must be strings.", WSGIWarning, stacklevel=3 + ) + if name.lower() == "status": + warn( + "The status header is not supported due to" + " conflicts with the CGI spec.", + WSGIWarning, + stacklevel=3, + ) + + if exc_info is not None and not isinstance(exc_info, tuple): + warn("Invalid value for exc_info.", WSGIWarning, stacklevel=3) + + headers = Headers(headers) + self.check_headers(headers) + + return status_code, headers + + def check_headers(self, headers: Headers) -> None: + etag = headers.get("etag") + + if etag is not None: + if etag.startswith(("W/", "w/")): + if etag.startswith("w/"): + warn( + "Weak etag indicator should be upper case.", + HTTPWarning, + stacklevel=4, + ) + + etag = etag[2:] + + if not (etag[:1] == etag[-1:] == '"'): + warn("Unquoted etag emitted.", HTTPWarning, stacklevel=4) + + location = headers.get("location") + + if location is not None: + if not urlparse(location).netloc: + warn( + "Absolute URLs required for location header.", + HTTPWarning, + stacklevel=4, + ) + + def check_iterator(self, app_iter: t.Iterable[bytes]) -> None: + if isinstance(app_iter, bytes): + warn( + "The application returned a bytestring. The response will send one" + " character at a time to the client, which will kill performance." + " Return a list or iterable instead.", + WSGIWarning, + stacklevel=3, + ) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Iterable[bytes]: + if len(args) != 2: + warn("A WSGI app takes two arguments.", WSGIWarning, stacklevel=2) + + if kwargs: + warn( + "A WSGI app does not take keyword arguments.", WSGIWarning, stacklevel=2 + ) + + environ: "WSGIEnvironment" = args[0] + start_response: "StartResponse" = args[1] + + self.check_environ(environ) + environ["wsgi.input"] = InputStream(environ["wsgi.input"]) + environ["wsgi.errors"] = ErrorStream(environ["wsgi.errors"]) + + # Hook our own file wrapper in so that applications will always + # iterate to the end and we can check the content length. + environ["wsgi.file_wrapper"] = FileWrapper + + headers_set: t.List[t.Any] = [] + chunks: t.List[int] = [] + + def checking_start_response( + *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[bytes], None]: + if len(args) not in {2, 3}: + warn( + f"Invalid number of arguments: {len(args)}, expected 2 or 3.", + WSGIWarning, + stacklevel=2, + ) + + if kwargs: + warn("'start_response' does not take keyword arguments.", WSGIWarning) + + status: str = args[0] + headers: t.List[t.Tuple[str, str]] = args[1] + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = (args[2] if len(args) == 3 else None) + + headers_set[:] = self.check_start_response(status, headers, exc_info) + return GuardedWrite(start_response(status, headers, exc_info), chunks) + + app_iter = self.app(environ, t.cast("StartResponse", checking_start_response)) + self.check_iterator(app_iter) + return GuardedIterator( + app_iter, t.cast(t.Tuple[int, Headers], headers_set), chunks + ) diff --git a/lib/python3.10/site-packages/werkzeug/middleware/profiler.py b/lib/python3.10/site-packages/werkzeug/middleware/profiler.py new file mode 100644 index 0000000..200dae0 --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/profiler.py @@ -0,0 +1,139 @@ +""" +Application Profiler +==================== + +This module provides a middleware that profiles each request with the +:mod:`cProfile` module. This can help identify bottlenecks in your code +that may be slowing down your application. + +.. autoclass:: ProfilerMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import os.path +import sys +import time +import typing as t +from pstats import Stats + +try: + from cProfile import Profile +except ImportError: + from profile import Profile # type: ignore + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class ProfilerMiddleware: + """Wrap a WSGI application and profile the execution of each + request. Responses are buffered so that timings are more exact. + + If ``stream`` is given, :class:`pstats.Stats` are written to it + after each request. If ``profile_dir`` is given, :mod:`cProfile` + data files are saved to that directory, one file per request. + + The filename can be customized by passing ``filename_format``. If + it is a string, it will be formatted using :meth:`str.format` with + the following fields available: + + - ``{method}`` - The request method; GET, POST, etc. + - ``{path}`` - The request path or 'root' should one not exist. + - ``{elapsed}`` - The elapsed time of the request. + - ``{time}`` - The time of the request. + + If it is a callable, it will be called with the WSGI ``environ`` + dict and should return a filename. + + :param app: The WSGI application to wrap. + :param stream: Write stats to this stream. Disable with ``None``. + :param sort_by: A tuple of columns to sort stats by. See + :meth:`pstats.Stats.sort_stats`. + :param restrictions: A tuple of restrictions to filter stats by. See + :meth:`pstats.Stats.print_stats`. + :param profile_dir: Save profile data files to this directory. + :param filename_format: Format string for profile data file names, + or a callable returning a name. See explanation above. + + .. code-block:: python + + from werkzeug.middleware.profiler import ProfilerMiddleware + app = ProfilerMiddleware(app) + + .. versionchanged:: 0.15 + Stats are written even if ``profile_dir`` is given, and can be + disable by passing ``stream=None``. + + .. versionadded:: 0.15 + Added ``filename_format``. + + .. versionadded:: 0.9 + Added ``restrictions`` and ``profile_dir``. + """ + + def __init__( + self, + app: "WSGIApplication", + stream: t.IO[str] = sys.stdout, + sort_by: t.Iterable[str] = ("time", "calls"), + restrictions: t.Iterable[t.Union[str, int, float]] = (), + profile_dir: t.Optional[str] = None, + filename_format: str = "{method}.{path}.{elapsed:.0f}ms.{time:.0f}.prof", + ) -> None: + self._app = app + self._stream = stream + self._sort_by = sort_by + self._restrictions = restrictions + self._profile_dir = profile_dir + self._filename_format = filename_format + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + response_body: t.List[bytes] = [] + + def catching_start_response(status, headers, exc_info=None): # type: ignore + start_response(status, headers, exc_info) + return response_body.append + + def runapp() -> None: + app_iter = self._app( + environ, t.cast("StartResponse", catching_start_response) + ) + response_body.extend(app_iter) + + if hasattr(app_iter, "close"): + app_iter.close() # type: ignore + + profile = Profile() + start = time.time() + profile.runcall(runapp) + body = b"".join(response_body) + elapsed = time.time() - start + + if self._profile_dir is not None: + if callable(self._filename_format): + filename = self._filename_format(environ) + else: + filename = self._filename_format.format( + method=environ["REQUEST_METHOD"], + path=environ["PATH_INFO"].strip("/").replace("/", ".") or "root", + elapsed=elapsed * 1000.0, + time=time.time(), + ) + filename = os.path.join(self._profile_dir, filename) + profile.dump_stats(filename) + + if self._stream is not None: + stats = Stats(profile, stream=self._stream) + stats.sort_stats(*self._sort_by) + print("-" * 80, file=self._stream) + path_info = environ.get("PATH_INFO", "") + print(f"PATH: {path_info!r}", file=self._stream) + stats.print_stats(*self._restrictions) + print(f"{'-' * 80}\n", file=self._stream) + + return [body] diff --git a/lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py b/lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py new file mode 100644 index 0000000..4cef7cc --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py @@ -0,0 +1,187 @@ +""" +X-Forwarded-For Proxy Fix +========================= + +This module provides a middleware that adjusts the WSGI environ based on +``X-Forwarded-`` headers that proxies in front of an application may +set. + +When an application is running behind a proxy server, WSGI may see the +request as coming from that server rather than the real client. Proxies +set various headers to track where the request actually came from. + +This middleware should only be used if the application is actually +behind such a proxy, and should be configured with the number of proxies +that are chained in front of it. Not all proxies set all the headers. +Since incoming headers can be faked, you must set how many proxies are +setting each header so the middleware knows what to trust. + +.. autoclass:: ProxyFix + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t + +from ..http import parse_list_header + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class ProxyFix: + """Adjust the WSGI environ based on ``X-Forwarded-`` that proxies in + front of the application may set. + + - ``X-Forwarded-For`` sets ``REMOTE_ADDR``. + - ``X-Forwarded-Proto`` sets ``wsgi.url_scheme``. + - ``X-Forwarded-Host`` sets ``HTTP_HOST``, ``SERVER_NAME``, and + ``SERVER_PORT``. + - ``X-Forwarded-Port`` sets ``HTTP_HOST`` and ``SERVER_PORT``. + - ``X-Forwarded-Prefix`` sets ``SCRIPT_NAME``. + + You must tell the middleware how many proxies set each header so it + knows what values to trust. It is a security issue to trust values + that came from the client rather than a proxy. + + The original values of the headers are stored in the WSGI + environ as ``werkzeug.proxy_fix.orig``, a dict. + + :param app: The WSGI application to wrap. + :param x_for: Number of values to trust for ``X-Forwarded-For``. + :param x_proto: Number of values to trust for ``X-Forwarded-Proto``. + :param x_host: Number of values to trust for ``X-Forwarded-Host``. + :param x_port: Number of values to trust for ``X-Forwarded-Port``. + :param x_prefix: Number of values to trust for + ``X-Forwarded-Prefix``. + + .. code-block:: python + + from werkzeug.middleware.proxy_fix import ProxyFix + # App is behind one proxy that sets the -For and -Host headers. + app = ProxyFix(app, x_for=1, x_host=1) + + .. versionchanged:: 1.0 + Deprecated code has been removed: + + * The ``num_proxies`` argument and attribute. + * The ``get_remote_addr`` method. + * The environ keys ``orig_remote_addr``, + ``orig_wsgi_url_scheme``, and ``orig_http_host``. + + .. versionchanged:: 0.15 + All headers support multiple values. The ``num_proxies`` + argument is deprecated. Each header is configured with a + separate number of trusted proxies. + + .. versionchanged:: 0.15 + Original WSGI environ values are stored in the + ``werkzeug.proxy_fix.orig`` dict. ``orig_remote_addr``, + ``orig_wsgi_url_scheme``, and ``orig_http_host`` are deprecated + and will be removed in 1.0. + + .. versionchanged:: 0.15 + Support ``X-Forwarded-Port`` and ``X-Forwarded-Prefix``. + + .. versionchanged:: 0.15 + ``X-Forwarded-Host`` and ``X-Forwarded-Port`` modify + ``SERVER_NAME`` and ``SERVER_PORT``. + """ + + def __init__( + self, + app: "WSGIApplication", + x_for: int = 1, + x_proto: int = 1, + x_host: int = 0, + x_port: int = 0, + x_prefix: int = 0, + ) -> None: + self.app = app + self.x_for = x_for + self.x_proto = x_proto + self.x_host = x_host + self.x_port = x_port + self.x_prefix = x_prefix + + def _get_real_value(self, trusted: int, value: t.Optional[str]) -> t.Optional[str]: + """Get the real value from a list header based on the configured + number of trusted proxies. + + :param trusted: Number of values to trust in the header. + :param value: Comma separated list header value to parse. + :return: The real value, or ``None`` if there are fewer values + than the number of trusted proxies. + + .. versionchanged:: 1.0 + Renamed from ``_get_trusted_comma``. + + .. versionadded:: 0.15 + """ + if not (trusted and value): + return None + values = parse_list_header(value) + if len(values) >= trusted: + return values[-trusted] + return None + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + """Modify the WSGI environ based on the various ``Forwarded`` + headers before calling the wrapped application. Store the + original environ values in ``werkzeug.proxy_fix.orig_{key}``. + """ + environ_get = environ.get + orig_remote_addr = environ_get("REMOTE_ADDR") + orig_wsgi_url_scheme = environ_get("wsgi.url_scheme") + orig_http_host = environ_get("HTTP_HOST") + environ.update( + { + "werkzeug.proxy_fix.orig": { + "REMOTE_ADDR": orig_remote_addr, + "wsgi.url_scheme": orig_wsgi_url_scheme, + "HTTP_HOST": orig_http_host, + "SERVER_NAME": environ_get("SERVER_NAME"), + "SERVER_PORT": environ_get("SERVER_PORT"), + "SCRIPT_NAME": environ_get("SCRIPT_NAME"), + } + } + ) + + x_for = self._get_real_value(self.x_for, environ_get("HTTP_X_FORWARDED_FOR")) + if x_for: + environ["REMOTE_ADDR"] = x_for + + x_proto = self._get_real_value( + self.x_proto, environ_get("HTTP_X_FORWARDED_PROTO") + ) + if x_proto: + environ["wsgi.url_scheme"] = x_proto + + x_host = self._get_real_value(self.x_host, environ_get("HTTP_X_FORWARDED_HOST")) + if x_host: + environ["HTTP_HOST"] = environ["SERVER_NAME"] = x_host + # "]" to check for IPv6 address without port + if ":" in x_host and not x_host.endswith("]"): + environ["SERVER_NAME"], environ["SERVER_PORT"] = x_host.rsplit(":", 1) + + x_port = self._get_real_value(self.x_port, environ_get("HTTP_X_FORWARDED_PORT")) + if x_port: + host = environ.get("HTTP_HOST") + if host: + # "]" to check for IPv6 address without port + if ":" in host and not host.endswith("]"): + host = host.rsplit(":", 1)[0] + environ["HTTP_HOST"] = f"{host}:{x_port}" + environ["SERVER_PORT"] = x_port + + x_prefix = self._get_real_value( + self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX") + ) + if x_prefix: + environ["SCRIPT_NAME"] = x_prefix + + return self.app(environ, start_response) diff --git a/lib/python3.10/site-packages/werkzeug/middleware/shared_data.py b/lib/python3.10/site-packages/werkzeug/middleware/shared_data.py new file mode 100644 index 0000000..2ec396c --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/middleware/shared_data.py @@ -0,0 +1,280 @@ +""" +Serve Shared Static Files +========================= + +.. autoclass:: SharedDataMiddleware + :members: is_allowed + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import mimetypes +import os +import pkgutil +import posixpath +import typing as t +from datetime import datetime +from datetime import timezone +from io import BytesIO +from time import time +from zlib import adler32 + +from ..http import http_date +from ..http import is_resource_modified +from ..security import safe_join +from ..utils import get_content_type +from ..wsgi import get_path_info +from ..wsgi import wrap_file + +_TOpener = t.Callable[[], t.Tuple[t.IO[bytes], datetime, int]] +_TLoader = t.Callable[[t.Optional[str]], t.Tuple[t.Optional[str], t.Optional[_TOpener]]] + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class SharedDataMiddleware: + + """A WSGI middleware which provides static content for development + environments or simple server setups. Its usage is quite simple:: + + import os + from werkzeug.middleware.shared_data import SharedDataMiddleware + + app = SharedDataMiddleware(app, { + '/shared': os.path.join(os.path.dirname(__file__), 'shared') + }) + + The contents of the folder ``./shared`` will now be available on + ``http://example.com/shared/``. This is pretty useful during development + because a standalone media server is not required. Files can also be + mounted on the root folder and still continue to use the application because + the shared data middleware forwards all unhandled requests to the + application, even if the requests are below one of the shared folders. + + If `pkg_resources` is available you can also tell the middleware to serve + files from package data:: + + app = SharedDataMiddleware(app, { + '/static': ('myapplication', 'static') + }) + + This will then serve the ``static`` folder in the `myapplication` + Python package. + + The optional `disallow` parameter can be a list of :func:`~fnmatch.fnmatch` + rules for files that are not accessible from the web. If `cache` is set to + `False` no caching headers are sent. + + Currently the middleware does not support non-ASCII filenames. If the + encoding on the file system happens to match the encoding of the URI it may + work but this could also be by accident. We strongly suggest using ASCII + only file names for static files. + + The middleware will guess the mimetype using the Python `mimetype` + module. If it's unable to figure out the charset it will fall back + to `fallback_mimetype`. + + :param app: the application to wrap. If you don't want to wrap an + application you can pass it :exc:`NotFound`. + :param exports: a list or dict of exported files and folders. + :param disallow: a list of :func:`~fnmatch.fnmatch` rules. + :param cache: enable or disable caching headers. + :param cache_timeout: the cache timeout in seconds for the headers. + :param fallback_mimetype: The fallback mimetype for unknown files. + + .. versionchanged:: 1.0 + The default ``fallback_mimetype`` is + ``application/octet-stream``. If a filename looks like a text + mimetype, the ``utf-8`` charset is added to it. + + .. versionadded:: 0.6 + Added ``fallback_mimetype``. + + .. versionchanged:: 0.5 + Added ``cache_timeout``. + """ + + def __init__( + self, + app: "WSGIApplication", + exports: t.Union[ + t.Dict[str, t.Union[str, t.Tuple[str, str]]], + t.Iterable[t.Tuple[str, t.Union[str, t.Tuple[str, str]]]], + ], + disallow: None = None, + cache: bool = True, + cache_timeout: int = 60 * 60 * 12, + fallback_mimetype: str = "application/octet-stream", + ) -> None: + self.app = app + self.exports: t.List[t.Tuple[str, _TLoader]] = [] + self.cache = cache + self.cache_timeout = cache_timeout + + if isinstance(exports, dict): + exports = exports.items() + + for key, value in exports: + if isinstance(value, tuple): + loader = self.get_package_loader(*value) + elif isinstance(value, str): + if os.path.isfile(value): + loader = self.get_file_loader(value) + else: + loader = self.get_directory_loader(value) + else: + raise TypeError(f"unknown def {value!r}") + + self.exports.append((key, loader)) + + if disallow is not None: + from fnmatch import fnmatch + + self.is_allowed = lambda x: not fnmatch(x, disallow) + + self.fallback_mimetype = fallback_mimetype + + def is_allowed(self, filename: str) -> bool: + """Subclasses can override this method to disallow the access to + certain files. However by providing `disallow` in the constructor + this method is overwritten. + """ + return True + + def _opener(self, filename: str) -> _TOpener: + return lambda: ( + open(filename, "rb"), + datetime.fromtimestamp(os.path.getmtime(filename), tz=timezone.utc), + int(os.path.getsize(filename)), + ) + + def get_file_loader(self, filename: str) -> _TLoader: + return lambda x: (os.path.basename(filename), self._opener(filename)) + + def get_package_loader(self, package: str, package_path: str) -> _TLoader: + load_time = datetime.now(timezone.utc) + provider = pkgutil.get_loader(package) + reader = provider.get_resource_reader(package) # type: ignore + + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is None: + return None, None + + path = safe_join(package_path, path) + + if path is None: + return None, None + + basename = posixpath.basename(path) + + try: + resource = reader.open_resource(path) + except OSError: + return None, None + + if isinstance(resource, BytesIO): + return ( + basename, + lambda: (resource, load_time, len(resource.getvalue())), + ) + + return ( + basename, + lambda: ( + resource, + datetime.fromtimestamp( + os.path.getmtime(resource.name), tz=timezone.utc + ), + os.path.getsize(resource.name), + ), + ) + + return loader + + def get_directory_loader(self, directory: str) -> _TLoader: + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is not None: + path = safe_join(directory, path) + + if path is None: + return None, None + else: + path = directory + + if os.path.isfile(path): + return os.path.basename(path), self._opener(path) + + return None, None + + return loader + + def generate_etag(self, mtime: datetime, file_size: int, real_filename: str) -> str: + real_filename = os.fsencode(real_filename) + timestamp = mtime.timestamp() + checksum = adler32(real_filename) & 0xFFFFFFFF + return f"wzsdm-{timestamp}-{file_size}-{checksum}" + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + path = get_path_info(environ) + file_loader = None + + for search_path, loader in self.exports: + if search_path == path: + real_filename, file_loader = loader(None) + + if file_loader is not None: + break + + if not search_path.endswith("/"): + search_path += "/" + + if path.startswith(search_path): + real_filename, file_loader = loader(path[len(search_path) :]) + + if file_loader is not None: + break + + if file_loader is None or not self.is_allowed(real_filename): # type: ignore + return self.app(environ, start_response) + + guessed_type = mimetypes.guess_type(real_filename) # type: ignore + mime_type = get_content_type(guessed_type[0] or self.fallback_mimetype, "utf-8") + f, mtime, file_size = file_loader() + + headers = [("Date", http_date())] + + if self.cache: + timeout = self.cache_timeout + etag = self.generate_etag(mtime, file_size, real_filename) # type: ignore + headers += [ + ("Etag", f'"{etag}"'), + ("Cache-Control", f"max-age={timeout}, public"), + ] + + if not is_resource_modified(environ, etag, last_modified=mtime): + f.close() + start_response("304 Not Modified", headers) + return [] + + headers.append(("Expires", http_date(time() + timeout))) + else: + headers.append(("Cache-Control", "public")) + + headers.extend( + ( + ("Content-Type", mime_type), + ("Content-Length", str(file_size)), + ("Last-Modified", http_date(mtime)), + ) + ) + start_response("200 OK", headers) + return wrap_file(environ, f) diff --git a/lib/python3.10/site-packages/werkzeug/py.typed b/lib/python3.10/site-packages/werkzeug/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/lib/python3.10/site-packages/werkzeug/routing/__init__.py b/lib/python3.10/site-packages/werkzeug/routing/__init__.py new file mode 100644 index 0000000..84b043f --- /dev/null +++ b/lib/python3.10/site-packages/werkzeug/routing/__init__.py @@ -0,0 +1,133 @@ +"""When it comes to combining multiple controller or view functions +(however you want to call them) you need a dispatcher. A simple way +would be applying regular expression tests on the ``PATH_INFO`` and +calling registered callback functions that return the value then. + +This module implements a much more powerful system than simple regular +expression matching because it can also convert values in the URLs and +build URLs. + +Here a simple example that creates a URL map for an application with +two subdomains (www and kb) and some URL rules: + +.. code-block:: python + + m = Map([ + # Static URLs + Rule('/', endpoint='static/index'), + Rule('/about', endpoint='static/about'), + Rule('/help', endpoint='static/help'), + # Knowledge Base + Subdomain('kb', [ + Rule('/', endpoint='kb/index'), + Rule('/browse/', endpoint='kb/browse'), + Rule('/browse//', endpoint='kb/browse'), + Rule('/browse//', endpoint='kb/browse') + ]) + ], default_subdomain='www') + +If the application doesn't use subdomains it's perfectly fine to not set +the default subdomain and not use the `Subdomain` rule factory. The +endpoint in the rules can be anything, for example import paths or +unique identifiers. The WSGI application can use those endpoints to get the +handler for that URL. It doesn't have to be a string at all but it's +recommended. + +Now it's possible to create a URL adapter for one of the subdomains and +build URLs: + +.. code-block:: python + + c = m.bind('example.com') + + c.build("kb/browse", dict(id=42)) + 'http://kb.example.com/browse/42/' + + c.build("kb/browse", dict()) + 'http://kb.example.com/browse/' + + c.build("kb/browse", dict(id=42, page=3)) + 'http://kb.example.com/browse/42/3' + + c.build("static/about") + '/about' + + c.build("static/index", force_external=True) + 'http://www.example.com/' + + c = m.bind('example.com', subdomain='kb') + + c.build("static/about") + 'http://www.example.com/about' + +The first argument to bind is the server name *without* the subdomain. +Per default it will assume that the script is mounted on the root, but +often that's not the case so you can provide the real mount point as +second argument: + +.. code-block:: python + + c = m.bind('example.com', '/applications/example') + +The third argument can be the subdomain, if not given the default +subdomain is used. For more details about binding have a look at the +documentation of the `MapAdapter`. + +And here is how you can match URLs: + +.. code-block:: python + + c = m.bind('example.com') + + c.match("/") + ('static/index', {}) + + c.match("/about") + ('static/about', {}) + + c = m.bind('example.com', '/', 'kb') + + c.match("/") + ('kb/index', {}) + + c.match("/browse/42/23") + ('kb/browse', {'id': 42, 'page': 23}) + +If matching fails you get a ``NotFound`` exception, if the rule thinks +it's a good idea to redirect (for example because the URL was defined +to have a slash at the end but the request was missing that slash) it +will raise a ``RequestRedirect`` exception. Both are subclasses of +``HTTPException`` so you can use those errors as responses in the +application. + +If matching succeeded but the URL rule was incompatible to the given +method (for example there were only rules for ``GET`` and ``HEAD`` but +routing tried to match a ``POST`` request) a ``MethodNotAllowed`` +exception is raised. +""" +from .converters import AnyConverter as AnyConverter +from .converters import BaseConverter as BaseConverter +from .converters import FloatConverter as FloatConverter +from .converters import IntegerConverter as IntegerConverter +from .converters import PathConverter as PathConverter +from .converters import UnicodeConverter as UnicodeConverter +from .converters import UUIDConverter as UUIDConverter +from .converters import ValidationError as ValidationError +from .exceptions import BuildError as BuildError +from .exceptions import NoMatch as NoMatch +from .exceptions import RequestAliasRedirect as RequestAliasRedirect +from .exceptions import RequestPath as RequestPath +from .exceptions import RequestRedirect as RequestRedirect +from .exceptions import RoutingException as RoutingException +from .exceptions import WebsocketMismatch as WebsocketMismatch +from .map import Map as Map +from .map import MapAdapter as MapAdapter +from .matcher import StateMachineMatcher as StateMachineMatcher +from .rules import EndpointPrefix as EndpointPrefix +from .rules import parse_converter_args as parse_converter_args +from .rules import Rule as Rule +from .rules import RuleFactory as RuleFactory +from .rules import RuleTemplate as RuleTemplate +from .rules import RuleTemplateFactory as RuleTemplateFactory +from .rules import Subdomain as Subdomain +from .rules import Submount as Submount diff --git a/lib/python3.10/site-packages/werkzeug/routing/__pycache__/__init__.cpython-310.pyc b/lib/python3.10/site-packages/werkzeug/routing/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4199fad110739894ede715d0fdc70ec8eecfd6d6 GIT binary patch literal 4633 zcmbtYU2_|^6{RfMl2@O$zVCjNN^VvQ7#u7 z02HNW`h)t|-_ob*wNL#Eed@V)cd3=+jMG#eLkC!VTwL69E+DhG7}W6d&%fV{{&BNb z`xjNJKUYxs2LIhRQ?*)L3v2OId?lG0UJ0*E5uOH~4yPH<0MCRojIRP;4X-l327E2N z#&{NZHk@TV2Rs+fF}@CbJ-p61NP^*fIL~+E5J9x8;oxxH;1d?D&w2LYvCH>)#TRjc6gidT5@N2H@wUE7Vy3B9^>1<_rv>) z?*KmtA27ZP{4jjT_#W`1@Dbztz@LSmF@6C2dH6Z-!~NR&Bl*K(t@fd>QlY(w%uqSu z4S}vsb$Td58hLF}7c}~2td8*M#EisPrk*E}Ng{k- z4cECjRVo%z#M))jM}1|RVp}*pq{+wfBp91f5{s@9GRu+^THC6_Q6jBS$C*{mVI|>} z^G*=xE79rfZXdj9@4S2cU8f^t8V3=UEJkYQmBotG)RocT%vy|<9+Uf#&F49i$w<+R zX)_28`r3)1iAOMtjT@>IOGf?h|BEx2FZ@usNvMJf!WCRb3Uy zk;Am`G)Bn8k*8Dm%?q}{37uQ?e(w)h5*zA{G@L?JnDz!6f+2;^)UjmW@oplkBz%Lf z=qrXY6Fr;~EdpoiNYXKhvG)DIkBxAnZfu59r%p7+<1wuy2Hkc3?GOVziG>H;W)L)+ zFfvwObrTZ}HaA6f;`=5I0)d~Q*b;AL*7y_GsO1Z>@3C6MHcwjjFju4As&5FD#+lKn z->N(A*V1XMj_d0i7yHVt8TpS5$Uj^j&{s+JvHsj%>HdZIeQL&uiVu}|A)T5mykB~y zQ6F?M)7hqIV;|eXpnKW;O5d(EW2esV8bk8t>Xt8$`5G?T)baEGZ!pi2$wT%0oMS3B zOg8`hI>YZbM67xeq;F4xWUG!CsjmmYPLF9<4XM~Dm)5t8AzfcpPY!E zPQfoDQsaeFJ|OZI%bbnk=%XGq7t?!kARR%$D0(vT#-23AL0<)BAeEHiaAjVRgro>k zP;P^1P%;H{HlP~hrwv(GMVgK8mbHpLG=2jWlR<6uSd8nXu zFb5J4lQt6Vn33RNQ-~ceN*DFz5j%m*6V6*w1n3ZnWOwA*Wr0;tUI3 zP`@rbK+?=iFNiK?uT}Cd*Od z@g#sABV2Uk8#>;4_GCQ|p?cr@Y_ruGbeokqil}crd(x_ZYPO#>(I;nNn>KLThidET z&zcgpJ-s+>p;9b5kBbeqatXSyjjEo(F9?K4wbe0>CzZ+8fgP#y{sF1ZIjCIuC(dBw zj44~BPZ!VRV}=$dadD;6e9#Egv<^XN4@Z>eD8T6W1#%!!&?!qW~8>UMnp^JFk#LFo+z?9Ly%Ky9i<+5xya$x7{5UT2u#o87DC*Cc90Ix zxCjC*kS6I~K`hLyIRan#8;FqP(;*{6FR^IgKp>c3?&lZA`-Z5uDk|q%MIe*Y$!X9Q zd$vd^I=s))EgM4jco&EIh_^LSykNpkatCB3hEBYOZ1CM8R$l4^iJa0Op9SdzYljqx zF$2;JtQ5p1;v>sbdqMmTlJRz~2^|Q?He7*=79`FI+|VXoL-NIrm{Jf)2w0rDhtBt1SRic3lX5|`0;#=k~z$GD5C<49$6=i)G+z~BT% zIceYm&W=(X8Uv!mN)qdERn<^`FB+6V%8XUs7-E0S|#96o`cEXr%Uk>GSM;X$16G;tRK9f_eNQpeP`a%+XWxiion=Tv~*>3pnbk*Cj(Gjz7RiXTG`88 zIEfFm-T0uo4zCI2-)hGmMdLKI3%`Oh2}5mlAFl-UR?-6szxdsV=A~D~Gh)|*4aaC% z%cOOx9hJ^(BLz6L&+Osmh~M+{`*nVSM0J6x2MP};Opp3%wSLy^`s50VK69vW_IkH2 zPG{R~C~&)d8cddSmi{(jr>U5s;wlx_sF@j8SDt)|au@h(4=<_WqZc}lGin~B~X5g;Loq9|4Itd-Uh8j7G4XX#7s%_YnDYt>+fJ^KJx#VIO zzPpe}1e{4i&7?1V$YaO#jNOOM_#qGZ5Bk{upwoTJdZc-prw3YH{pxjt(`McD z49^U#wq3V%O&EI_dBw9lJIJ@b5$U2=Lb}B164JBY9MW@~o<+LsokRK@r{|EK_s%1IUd*9=8R-S@0@4>aeGchG z?;_F{x&FK;;;$rTMOmB^^WM@wW$WiL=LK;A@uHZyq_vDonz-m)TE}YN(<+yrVeMM& znSr>Xr*n;#8z+sf3>qJGqeMK@RlfPQ+i6nG@rTOpAjD-vLaXbZhF#NX$I!Ex&b{vj zzUL->6yB3ElD)q_$#4YatT@htmg73I8wjTvg^z_ygmk3q$0Bx;T|aijK~r?73nT?s zEI4?)2o=I8aoTRu+~u-nS4t5k&ZCEKId152UMLP!26{@QFT53QU8`7WuF(kHwrDic zLZi`+JWK)a#ReAc27{7pqv1u(M&ol$&R~rkJr~tSv5;{!5K&mYE8_hm>Qp<2$!-)j z-j&gwXeM#B6}a(!HSo6wCEr}Rxmu0=MBM1O&3$)A#MLK4?)OA@rz)dv;)grc(FVjT zokN+yfHY`qA`V8`@c3u>aM_1CS7rg?Gbv`Y9*Nw%-@UVI>QPOE*y|L4Zq~iv` z$x+5DJ^OkNvG|He$r?xA@!fsYeDZVPOM~Q zSS7U|yFph>%!OLeecwRf6X`>GKFTq)f{X`8zg97xmu4nI)l8r6jY|1>IAbr-)86wWZh*2WjSs@OO5TbhhKlq~XU=0JsQuQawq{ zH^M`Cff{^`qDvGx6rG$bztJAc5+XWwhN2wy*D?_Fmy88-$>h>Afbak5mR8S0NM_UWqtK__9Lb5B!NG45 zqK(AdAy5LSd7|ZZgJi6L;LB|i@Wp_#LkGu$U2(R%3By+u28T`*3a8^HyG|^2+Q2E>=%^*E^CbVJ5SKWqkFPdKgek%&N}41Gn7?#M+ul67oI- zP+q@Q?J$O|)6eZ|m1XX6tax2b;d&s#on-erw<>Fa8}2k{OHf_)wuVD@+d%Nn8t=mz zgUH$zbj_B+>0u2&RQ;%WZAfyv+jdl*6ScUt8W6kib~jF(ZQ<-l;X<2?W=69+d4N=c zklwjDIh1=aF_e4o;-R?b!4$_Ei37KpOrM?Fcu6u{Q;5Z2n8%V-4{5$VoI#pVS#ln= zn^bT3kU&wIWH)XhO0;9`Q@yW$rt4bY^0cll&wGH0zICjBta-*K=8+vP^-Yv$^0H?h zWx@pSaeUTB`pz)sIr`xxU=92-quj zYRBCUv^j}tYWiWKuJ8x;QP>M zoM0&r@*0}6oENh>eO}KQ8NFyM>Seum>9o*|AiZL$J+D;?)8I&co#s`g=+64c+>KVHp2on8ttSEaSg&w($oe zv-n(6{WFk6SV~WPAJJ(@@=T(gf;D+7!>~g{vk2{8U|pRNHgxqsr!y3hzAmLj0O<(~ z{RCRaoo$4*B^k9`j;3A~Im2tkAokdh=(?=s2ZJB(Uk;+Uuv&a$&Bg3hwzw>v;HB>8xkovW=VTHbc$)e2;3M=&e<(=mbIQF-}Gu2XEtTqB61G994DHs7-(j{1p2S~WG;((pTs1D5-?g(#f z&AGL5Yt$0dwu`=FX8@tXbDr#q5SZ-;9)Y(@#8hF;=9uW)JRO$tN%lj+O+rq>9@Cv4 z7jlR$#1(>Rdb($P3Zmy(Pqn^rS33p>K!EK}OqALKvF(}HUtfE!_nSmvh7S=D8sI&I zcoET#*4IAF9_h&dOMYQ|1R~GUS20pU3Q&Z&>2?IAR#sE}KuP9E4X1_mz>kw=)b8B= z5%o$#ENZ>V_zfJ%*@ zQQ5JscKygmEDt=4cE4``I03#t(*c@219$!O&XWp=DO^GHQ`-6b5ez79u6<&@54QOc zj44R4@m#-F8=QjtHfpC9-I>#SpI_e*Fn2ogwnyDk|He-)YrR({R<4-a*wzml$=A`K zSH4D9nCz+nHdJiheue3`Y4A)O!ASGc0^fKx?0~K#_FFHq04NxbPfd~u+!lI?i4GP( z8!sCRdhh&{DOP4)4Ae{rnHm!0%DD%?4a;1X%+n2M#x0 zp(;E-`RWv{mn9mo@|Uka`!{Ua{Tg)s6u!@bD@ivhReN$q{KhKuE=qT4+sQ!SGs;`I zA(HaXoDmUzdg6aZG(02taM=4$w}f5KkWv(R&xEJLsu%KhK7+rkw?zIKs7xC^ne5&S zbNb@wtt5&tfitZlE7&=&{Ipar!5cH{&7#g66fF5;tU63$N+Wj`dE}F^>f~{uw81_Z zNPqo2tKkLQluPMct=rxf^5m|(N#@dt-MsZ6Okfk8RM_HE-nt(|ZZc{GV$A2a1`R4C zRM#3OpWVVXq%&c+4T{Zflub$3xORU`)f8L)f$$ohzvCw{OmROXdmKhs?C*raQ#^CX zLC{#EcLGETF^NjwmKlOPs1~qGa84MY%sH7O_F3ihEtF>ZFhv_#Qa?j8w5Uc=giqav z5zfm8=v@9aMI@#2Ekw`*3@S_>r<6}a{hy*;Jd4Q6<@BPS;XfGqOQ-gJq=U{X08&}B z-VN&NeMGcgSyJFn@B6SPY3)CQVo>WpA{C)n_Z3zb*1i_Mf;^~SF!2iK+548P4B7$J z)vjcC;i(BO%-$XOeGE9Z4^xb9HiUmclcU{PzzPfc0>s4lBZZ6!*TSXKtNjYj1p-ny z7Y3RiHUX{4kmbIPHRA0v${EeuQu=^rOGlI1y_O#Y)0_ni%pcQybBJa!-y#h2-r|%w z!doz*Cg}pxaqv+PM0hkQjZ6|!i_oh#UWXUxWt8BDFUtw8Fr>VVqR$YRh!l<9mD8h+ z-^q%lM5cDXa$zclF?_L+zze4>OLH6Wce$XIaGf^X5Smi~G0cRoqg=9FTH8^iObNAb ztguE7jWh?^4GStclr-NLD>1SPo*=L&7RbqA&tfl?odHYZ`B_WDcy458zgQ?Q6pYN0 zE~$qm!o)+{d+ct#KA&@E$BDUL3%clX#{UuK4luLtM6GPff7zIQlO57D^b<