From 989cb8087787b4a06bb23f53a917e70b45c68665 Mon Sep 17 00:00:00 2001 From: Barzder Date: Wed, 27 Dec 2023 19:02:53 +0100 Subject: [PATCH] Speichern der manuellen 'theme' Auswahl in der session; code fuer mehrere buttons implementiert --- __pycache__/app.cpython-310.pyc | Bin 0 -> 506 bytes app.py | 6 +- env/bin/Activate.ps1 | 247 + env/bin/activate | 69 + env/bin/activate.csh | 26 + env/bin/activate.fish | 69 + env/bin/flask | 8 + env/bin/pip | 8 + env/bin/pip3 | 8 + env/bin/pip3.10 | 8 + env/bin/python | 1 + env/bin/python3 | 1 + env/bin/python3.10 | 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 | 59 + .../Jinja2-3.1.2.dist-info/REQUESTED | 0 .../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.3.dist-info/INSTALLER | 1 + .../MarkupSafe-2.1.3.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.3.dist-info/METADATA | 93 + .../MarkupSafe-2.1.3.dist-info/RECORD | 15 + .../MarkupSafe-2.1.3.dist-info/REQUESTED | 0 .../MarkupSafe-2.1.3.dist-info/WHEEL | 6 + .../MarkupSafe-2.1.3.dist-info/top_level.txt | 1 + .../site-packages/_distutils_hack/__init__.py | 132 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5122 bytes .../__pycache__/override.cpython-310.pyc | Bin 0 -> 247 bytes .../site-packages/_distutils_hack/override.py | 1 + .../blinker-1.7.0.dist-info/INSTALLER | 1 + .../blinker-1.7.0.dist-info/LICENSE.rst | 20 + .../blinker-1.7.0.dist-info/METADATA | 62 + .../blinker-1.7.0.dist-info/RECORD | 15 + .../blinker-1.7.0.dist-info/REQUESTED | 0 .../blinker-1.7.0.dist-info/WHEEL | 4 + .../site-packages/blinker/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 511 bytes .../__pycache__/_saferef.cpython-310.pyc | Bin 0 -> 7198 bytes .../__pycache__/_utilities.cpython-310.pyc | Bin 0 -> 3537 bytes .../blinker/__pycache__/base.cpython-310.pyc | Bin 0 -> 17511 bytes .../site-packages/blinker/_saferef.py | 230 + .../site-packages/blinker/_utilities.py | 105 + .../python3.10/site-packages/blinker/base.py | 558 ++ .../python3.10/site-packages/blinker/py.typed | 0 .../click-8.1.7.dist-info/INSTALLER | 1 + .../click-8.1.7.dist-info/LICENSE.rst | 28 + .../click-8.1.7.dist-info/METADATA | 103 + .../click-8.1.7.dist-info/RECORD | 40 + .../click-8.1.7.dist-info/REQUESTED | 0 .../site-packages/click-8.1.7.dist-info/WHEEL | 5 + .../click-8.1.7.dist-info/top_level.txt | 1 + .../site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2630 bytes .../click/__pycache__/_compat.cpython-310.pyc | Bin 0 -> 15688 bytes .../__pycache__/_termui_impl.cpython-310.pyc | Bin 0 -> 16328 bytes .../__pycache__/_textwrap.cpython-310.pyc | Bin 0 -> 1564 bytes .../__pycache__/_winconsole.cpython-310.pyc | Bin 0 -> 7680 bytes .../click/__pycache__/core.cpython-310.pyc | Bin 0 -> 91158 bytes .../__pycache__/decorators.cpython-310.pyc | Bin 0 -> 17228 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10272 bytes .../__pycache__/formatting.cpython-310.pyc | Bin 0 -> 9477 bytes .../click/__pycache__/globals.cpython-310.pyc | Bin 0 -> 2449 bytes .../click/__pycache__/parser.cpython-310.pyc | Bin 0 -> 13690 bytes .../shell_completion.cpython-310.pyc | Bin 0 -> 16865 bytes .../click/__pycache__/termui.cpython-310.pyc | Bin 0 -> 26150 bytes .../click/__pycache__/testing.cpython-310.pyc | Bin 0 -> 15223 bytes .../click/__pycache__/types.cpython-310.pyc | Bin 0 -> 33707 bytes .../click/__pycache__/utils.cpython-310.pyc | Bin 0 -> 18863 bytes .../python3.10/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 739 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../python3.10/site-packages/click/core.py | 3042 ++++++ .../site-packages/click/decorators.py | 561 ++ .../site-packages/click/exceptions.py | 288 + .../site-packages/click/formatting.py | 301 + .../python3.10/site-packages/click/globals.py | 68 + .../python3.10/site-packages/click/parser.py | 529 + .../python3.10/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .../python3.10/site-packages/click/termui.py | 784 ++ .../python3.10/site-packages/click/testing.py | 479 + .../python3.10/site-packages/click/types.py | 1089 +++ .../python3.10/site-packages/click/utils.py | 624 ++ .../site-packages/distutils-precedence.pth | 1 + .../flask-3.0.0.dist-info/INSTALLER | 1 + .../flask-3.0.0.dist-info/LICENSE.rst | 28 + .../flask-3.0.0.dist-info/METADATA | 116 + .../flask-3.0.0.dist-info/RECORD | 58 + .../flask-3.0.0.dist-info/REQUESTED | 0 .../site-packages/flask-3.0.0.dist-info/WHEEL | 4 + .../flask-3.0.0.dist-info/entry_points.txt | 3 + .../site-packages/flask/__init__.py | 60 + .../site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2301 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 226 bytes .../flask/__pycache__/app.cpython-310.pyc | Bin 0 -> 49697 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 3437 bytes .../flask/__pycache__/cli.cpython-310.pyc | Bin 0 -> 27038 bytes .../flask/__pycache__/config.cpython-310.pyc | Bin 0 -> 12883 bytes .../flask/__pycache__/ctx.cpython-310.pyc | Bin 0 -> 14693 bytes .../__pycache__/debughelpers.cpython-310.pyc | Bin 0 -> 6024 bytes .../flask/__pycache__/globals.cpython-310.pyc | Bin 0 -> 1594 bytes .../flask/__pycache__/helpers.cpython-310.pyc | Bin 0 -> 21590 bytes .../flask/__pycache__/logging.cpython-310.pyc | Bin 0 -> 2557 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 13270 bytes .../flask/__pycache__/signals.cpython-310.pyc | Bin 0 -> 824 bytes .../__pycache__/templating.cpython-310.pyc | Bin 0 -> 7101 bytes .../flask/__pycache__/testing.cpython-310.pyc | Bin 0 -> 9710 bytes .../flask/__pycache__/typing.cpython-310.pyc | Bin 0 -> 1826 bytes .../flask/__pycache__/views.cpython-310.pyc | Bin 0 -> 5480 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 5212 bytes env/lib/python3.10/site-packages/flask/app.py | 1478 +++ .../site-packages/flask/blueprints.py | 91 + env/lib/python3.10/site-packages/flask/cli.py | 1068 +++ .../python3.10/site-packages/flask/config.py | 347 + env/lib/python3.10/site-packages/flask/ctx.py | 440 + .../site-packages/flask/debughelpers.py | 160 + .../python3.10/site-packages/flask/globals.py | 51 + .../python3.10/site-packages/flask/helpers.py | 623 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 6008 bytes .../json/__pycache__/provider.cpython-310.pyc | Bin 0 -> 7688 bytes .../json/__pycache__/tag.cpython-310.pyc | Bin 0 -> 11115 bytes .../site-packages/flask/json/provider.py | 216 + .../site-packages/flask/json/tag.py | 314 + .../python3.10/site-packages/flask/logging.py | 76 + .../python3.10/site-packages/flask/py.typed | 0 .../site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-310.pyc | Bin 0 -> 28551 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 22773 bytes .../__pycache__/scaffold.cpython-310.pyc | Bin 0 -> 23943 bytes .../site-packages/flask/sansio/app.py | 964 ++ .../site-packages/flask/sansio/blueprints.py | 626 ++ .../site-packages/flask/sansio/scaffold.py | 802 ++ .../site-packages/flask/sessions.py | 367 + .../python3.10/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 221 + .../python3.10/site-packages/flask/testing.py | 295 + .../python3.10/site-packages/flask/typing.py | 88 + .../python3.10/site-packages/flask/views.py | 190 + .../site-packages/flask/wrappers.py | 173 + .../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 | 24 + .../itsdangerous-2.1.2.dist-info/REQUESTED | 0 .../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 -> 879 bytes .../__pycache__/_json.cpython-310.pyc | Bin 0 -> 934 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1883 bytes .../__pycache__/exc.cpython-310.pyc | Bin 0 -> 3422 bytes .../__pycache__/serializer.cpython-310.pyc | Bin 0 -> 9706 bytes .../__pycache__/signer.cpython-310.pyc | Bin 0 -> 8474 bytes .../__pycache__/timed.cpython-310.pyc | Bin 0 -> 6488 bytes .../__pycache__/url_safe.cpython-310.pyc | Bin 0 -> 2707 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 -> 1615 bytes .../__pycache__/_identifier.cpython-310.pyc | Bin 0 -> 2090 bytes .../__pycache__/async_utils.cpython-310.pyc | Bin 0 -> 2727 bytes .../__pycache__/bccache.cpython-310.pyc | Bin 0 -> 13961 bytes .../__pycache__/compiler.cpython-310.pyc | Bin 0 -> 54564 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 1551 bytes .../jinja2/__pycache__/debug.cpython-310.pyc | Bin 0 -> 4007 bytes .../__pycache__/defaults.cpython-310.pyc | Bin 0 -> 1351 bytes .../__pycache__/environment.cpython-310.pyc | Bin 0 -> 53401 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5550 bytes .../jinja2/__pycache__/ext.cpython-310.pyc | Bin 0 -> 25712 bytes .../__pycache__/filters.cpython-310.pyc | Bin 0 -> 51200 bytes .../__pycache__/idtracking.cpython-310.pyc | Bin 0 -> 11102 bytes .../jinja2/__pycache__/lexer.cpython-310.pyc | Bin 0 -> 20452 bytes .../__pycache__/loaders.cpython-310.pyc | Bin 0 -> 20535 bytes .../jinja2/__pycache__/meta.cpython-310.pyc | Bin 0 -> 3831 bytes .../__pycache__/nativetypes.cpython-310.pyc | Bin 0 -> 5026 bytes .../jinja2/__pycache__/nodes.cpython-310.pyc | Bin 0 -> 40317 bytes .../__pycache__/optimizer.cpython-310.pyc | Bin 0 -> 1971 bytes .../jinja2/__pycache__/parser.cpython-310.pyc | Bin 0 -> 27698 bytes .../__pycache__/runtime.cpython-310.pyc | Bin 0 -> 32164 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 11983 bytes .../jinja2/__pycache__/tests.cpython-310.pyc | Bin 0 -> 6705 bytes .../jinja2/__pycache__/utils.cpython-310.pyc | Bin 0 -> 24524 bytes .../__pycache__/visitor.cpython-310.pyc | Bin 0 -> 3990 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 + .../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 + .../python3.10/site-packages/jinja2/ext.py | 859 ++ .../site-packages/jinja2/filters.py | 1840 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.10/site-packages/jinja2/lexer.py | 866 ++ .../site-packages/jinja2/loaders.py | 661 ++ .../python3.10/site-packages/jinja2/meta.py | 111 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.10/site-packages/jinja2/nodes.py | 1204 +++ .../site-packages/jinja2/optimizer.py | 47 + .../python3.10/site-packages/jinja2/parser.py | 1032 ++ .../python3.10/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1053 ++ .../site-packages/jinja2/sandbox.py | 428 + .../python3.10/site-packages/jinja2/tests.py | 255 + .../python3.10/site-packages/jinja2/utils.py | 755 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 304 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 11267 bytes .../__pycache__/_native.cpython-310.pyc | Bin 0 -> 2015 bytes .../site-packages/markupsafe/_native.py | 63 + .../site-packages/markupsafe/_speedups.c | 320 + .../_speedups.cpython-310-x86_64-linux-gnu.so | Bin 0 -> 44240 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../site-packages/markupsafe/py.typed | 0 .../pip-22.0.2.dist-info/INSTALLER | 1 + .../pip-22.0.2.dist-info/LICENSE.txt | 20 + .../pip-22.0.2.dist-info/METADATA | 92 + .../site-packages/pip-22.0.2.dist-info/RECORD | 1037 ++ .../pip-22.0.2.dist-info/REQUESTED | 0 .../site-packages/pip-22.0.2.dist-info/WHEEL | 5 + .../pip-22.0.2.dist-info/entry_points.txt | 5 + .../pip-22.0.2.dist-info/top_level.txt | 1 + .../python3.10/site-packages/pip/__init__.py | 13 + .../python3.10/site-packages/pip/__main__.py | 31 + .../pip/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 640 bytes .../pip/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 602 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 761 bytes .../__pycache__/build_env.cpython-310.pyc | Bin 0 -> 9605 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 8388 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 11134 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 23131 bytes .../__pycache__/main.cpython-310.pyc | Bin 0 -> 626 bytes .../__pycache__/pyproject.cpython-310.pyc | Bin 0 -> 3545 bytes .../self_outdated_check.cpython-310.pyc | Bin 0 -> 4585 bytes .../__pycache__/wheel_builder.cpython-310.pyc | Bin 0 -> 9147 bytes .../site-packages/pip/_internal/build_env.py | 296 + .../site-packages/pip/_internal/cache.py | 264 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 281 bytes .../autocompletion.cpython-310.pyc | Bin 0 -> 5314 bytes .../__pycache__/base_command.cpython-310.pyc | Bin 0 -> 6257 bytes .../__pycache__/cmdoptions.cpython-310.pyc | Bin 0 -> 22556 bytes .../command_context.cpython-310.pyc | Bin 0 -> 1315 bytes .../cli/__pycache__/main.cpython-310.pyc | Bin 0 -> 1379 bytes .../__pycache__/main_parser.cpython-310.pyc | Bin 0 -> 2165 bytes .../cli/__pycache__/parser.cpython-310.pyc | Bin 0 -> 9952 bytes .../__pycache__/progress_bars.cpython-310.pyc | Bin 0 -> 9241 bytes .../__pycache__/req_command.cpython-310.pyc | Bin 0 -> 13542 bytes .../cli/__pycache__/spinners.cpython-310.pyc | Bin 0 -> 4955 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 360 bytes .../pip/_internal/cli/autocompletion.py | 171 + .../pip/_internal/cli/base_command.py | 220 + .../pip/_internal/cli/cmdoptions.py | 1018 ++ .../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 | 292 + .../pip/_internal/cli/progress_bars.py | 321 + .../pip/_internal/cli/req_command.py | 506 + .../pip/_internal/cli/spinners.py | 157 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 127 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3144 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 6185 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 1578 bytes .../__pycache__/completion.cpython-310.pyc | Bin 0 -> 3145 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 8327 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 6682 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 3992 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 2658 bytes .../commands/__pycache__/hash.cpython-310.pyc | Bin 0 -> 2157 bytes .../commands/__pycache__/help.cpython-310.pyc | Bin 0 -> 1318 bytes .../__pycache__/index.cpython-310.pyc | Bin 0 -> 4641 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 17800 bytes .../commands/__pycache__/list.cpython-310.pyc | Bin 0 -> 10367 bytes .../__pycache__/search.cpython-310.pyc | Bin 0 -> 5371 bytes .../commands/__pycache__/show.cpython-310.pyc | Bin 0 -> 6124 bytes .../__pycache__/uninstall.cpython-310.pyc | Bin 0 -> 3115 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4847 bytes .../pip/_internal/commands/cache.py | 223 + .../pip/_internal/commands/check.py | 53 + .../pip/_internal/commands/completion.py | 96 + .../pip/_internal/commands/configuration.py | 266 + .../pip/_internal/commands/debug.py | 202 + .../pip/_internal/commands/download.py | 140 + .../pip/_internal/commands/freeze.py | 97 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 139 + .../pip/_internal/commands/install.py | 771 ++ .../pip/_internal/commands/list.py | 363 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 178 + .../pip/_internal/commands/uninstall.py | 105 + .../pip/_internal/commands/wheel.py | 178 + .../pip/_internal/configuration.py | 366 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 808 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1865 bytes .../__pycache__/installed.cpython-310.pyc | Bin 0 -> 1242 bytes .../__pycache__/sdist.cpython-310.pyc | Bin 0 -> 4454 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1609 bytes .../pip/_internal/distributions/base.py | 36 + .../pip/_internal/distributions/installed.py | 20 + .../pip/_internal/distributions/sdist.py | 127 + .../pip/_internal/distributions/wheel.py | 31 + .../site-packages/pip/_internal/exceptions.py | 658 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 235 bytes .../__pycache__/collector.cpython-310.pyc | Bin 0 -> 19314 bytes .../package_finder.cpython-310.pyc | Bin 0 -> 28123 bytes .../index/__pycache__/sources.cpython-310.pyc | Bin 0 -> 7128 bytes .../pip/_internal/index/collector.py | 648 ++ .../pip/_internal/index/package_finder.py | 1004 ++ .../pip/_internal/index/sources.py | 224 + .../pip/_internal/locations/__init__.py | 520 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 12395 bytes .../__pycache__/_distutils.cpython-310.pyc | Bin 0 -> 4663 bytes .../__pycache__/_sysconfig.cpython-310.pyc | Bin 0 -> 6246 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1545 bytes .../pip/_internal/locations/_distutils.py | 169 + .../pip/_internal/locations/_sysconfig.py | 219 + .../pip/_internal/locations/base.py | 52 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 62 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2301 bytes .../metadata/__pycache__/base.cpython-310.pyc | Bin 0 -> 20855 bytes .../__pycache__/pkg_resources.cpython-310.pyc | Bin 0 -> 9871 bytes .../pip/_internal/metadata/base.py | 546 ++ .../pip/_internal/metadata/pkg_resources.py | 256 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 269 bytes .../__pycache__/candidate.cpython-310.pyc | Bin 0 -> 1421 bytes .../__pycache__/direct_url.cpython-310.pyc | Bin 0 -> 7294 bytes .../format_control.cpython-310.pyc | Bin 0 -> 2746 bytes .../models/__pycache__/index.cpython-310.pyc | Bin 0 -> 1238 bytes .../models/__pycache__/link.cpython-310.pyc | Bin 0 -> 10170 bytes .../models/__pycache__/scheme.cpython-310.pyc | Bin 0 -> 1037 bytes .../__pycache__/search_scope.cpython-310.pyc | Bin 0 -> 3492 bytes .../selection_prefs.cpython-310.pyc | Bin 0 -> 1699 bytes .../__pycache__/target_python.cpython-310.pyc | Bin 0 -> 3450 bytes .../models/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4366 bytes .../pip/_internal/models/candidate.py | 34 + .../pip/_internal/models/direct_url.py | 220 + .../pip/_internal/models/format_control.py | 80 + .../pip/_internal/models/index.py | 28 + .../pip/_internal/models/link.py | 288 + .../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 | 89 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 257 bytes .../network/__pycache__/auth.cpython-310.pyc | Bin 0 -> 7525 bytes .../network/__pycache__/cache.cpython-310.pyc | Bin 0 -> 2938 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 5504 bytes .../__pycache__/lazy_wheel.cpython-310.pyc | Bin 0 -> 8412 bytes .../__pycache__/session.cpython-310.pyc | Bin 0 -> 10733 bytes .../network/__pycache__/utils.cpython-310.pyc | Bin 0 -> 1453 bytes .../__pycache__/xmlrpc.cpython-310.pyc | Bin 0 -> 2070 bytes .../pip/_internal/network/auth.py | 323 + .../pip/_internal/network/cache.py | 69 + .../pip/_internal/network/download.py | 185 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 454 + .../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 -> 205 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 4018 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 6203 bytes .../__pycache__/prepare.cpython-310.pyc | Bin 0 -> 14901 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 211 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 1438 bytes .../metadata_editable.cpython-310.pyc | Bin 0 -> 1472 bytes .../metadata_legacy.cpython-310.pyc | Bin 0 -> 2383 bytes .../build/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1228 bytes .../wheel_editable.cpython-310.pyc | Bin 0 -> 1452 bytes .../__pycache__/wheel_legacy.cpython-310.pyc | Bin 0 -> 2768 bytes .../_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 -> 269 bytes .../editable_legacy.cpython-310.pyc | Bin 0 -> 1556 bytes .../__pycache__/legacy.cpython-310.pyc | Bin 0 -> 3340 bytes .../install/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 21098 bytes .../operations/install/editable_legacy.py | 47 + .../_internal/operations/install/legacy.py | 120 + .../pip/_internal/operations/install/wheel.py | 738 ++ .../pip/_internal/operations/prepare.py | 642 ++ .../site-packages/pip/_internal/pyproject.py | 168 + .../pip/_internal/req/__init__.py | 94 + .../req/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2605 bytes .../__pycache__/constructors.cpython-310.pyc | Bin 0 -> 12168 bytes .../req/__pycache__/req_file.cpython-310.pyc | Bin 0 -> 13496 bytes .../__pycache__/req_install.cpython-310.pyc | Bin 0 -> 22185 bytes .../req/__pycache__/req_set.cpython-310.pyc | Bin 0 -> 5845 bytes .../__pycache__/req_tracker.cpython-310.pyc | Bin 0 -> 4313 bytes .../__pycache__/req_uninstall.cpython-310.pyc | Bin 0 -> 18951 bytes .../pip/_internal/req/constructors.py | 490 + .../pip/_internal/req/req_file.py | 536 ++ .../pip/_internal/req/req_install.py | 858 ++ .../pip/_internal/req/req_set.py | 189 + .../pip/_internal/req/req_tracker.py | 124 + .../pip/_internal/req/req_uninstall.py | 633 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 205 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1057 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 212 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 12299 bytes .../_internal/resolution/legacy/resolver.py | 467 + .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 216 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 6459 bytes .../__pycache__/candidates.cpython-310.pyc | Bin 0 -> 18366 bytes .../__pycache__/factory.cpython-310.pyc | Bin 0 -> 19224 bytes .../found_candidates.cpython-310.pyc | Bin 0 -> 4876 bytes .../__pycache__/provider.cpython-310.pyc | Bin 0 -> 7718 bytes .../__pycache__/reporter.cpython-310.pyc | Bin 0 -> 3185 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 7474 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 8111 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 547 ++ .../resolution/resolvelib/factory.py | 739 ++ .../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 | 292 + .../pip/_internal/self_outdated_check.py | 189 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 200 bytes .../utils/__pycache__/_log.cpython-310.pyc | Bin 0 -> 1528 bytes .../utils/__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 1626 bytes .../utils/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1516 bytes .../compatibility_tags.cpython-310.pyc | Bin 0 -> 4085 bytes .../__pycache__/datetime.cpython-310.pyc | Bin 0 -> 523 bytes .../__pycache__/deprecation.cpython-310.pyc | Bin 0 -> 3321 bytes .../direct_url_helpers.cpython-310.pyc | Bin 0 -> 2091 bytes .../distutils_args.cpython-310.pyc | Bin 0 -> 1107 bytes .../__pycache__/egg_link.cpython-310.pyc | Bin 0 -> 2156 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1313 bytes .../__pycache__/entrypoints.cpython-310.pyc | Bin 0 -> 1310 bytes .../__pycache__/filesystem.cpython-310.pyc | Bin 0 -> 5168 bytes .../__pycache__/filetypes.cpython-310.pyc | Bin 0 -> 950 bytes .../utils/__pycache__/glibc.cpython-310.pyc | Bin 0 -> 1679 bytes .../utils/__pycache__/hashes.cpython-310.pyc | Bin 0 -> 5202 bytes .../inject_securetransport.cpython-310.pyc | Bin 0 -> 995 bytes .../utils/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9639 bytes .../utils/__pycache__/misc.cpython-310.pyc | Bin 0 -> 19405 bytes .../utils/__pycache__/models.cpython-310.pyc | Bin 0 -> 1996 bytes .../__pycache__/packaging.cpython-310.pyc | Bin 0 -> 2088 bytes .../setuptools_build.cpython-310.pyc | Bin 0 -> 4603 bytes .../__pycache__/subprocess.cpython-310.pyc | Bin 0 -> 5782 bytes .../__pycache__/temp_dir.cpython-310.pyc | Bin 0 -> 7305 bytes .../__pycache__/unpacking.cpython-310.pyc | Bin 0 -> 6660 bytes .../utils/__pycache__/urls.cpython-310.pyc | Bin 0 -> 1593 bytes .../__pycache__/virtualenv.cpython-310.pyc | Bin 0 -> 3296 bytes .../utils/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4421 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 | 42 + .../pip/_internal/utils/egg_link.py | 75 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 27 + .../pip/_internal/utils/filesystem.py | 182 + .../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 | 343 + .../site-packages/pip/_internal/utils/misc.py | 653 ++ .../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 | 258 + .../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 -> 523 bytes .../vcs/__pycache__/bazaar.cpython-310.pyc | Bin 0 -> 3350 bytes .../vcs/__pycache__/git.cpython-310.pyc | Bin 0 -> 12553 bytes .../vcs/__pycache__/mercurial.cpython-310.pyc | Bin 0 -> 5069 bytes .../__pycache__/subversion.cpython-310.pyc | Bin 0 -> 8457 bytes .../versioncontrol.cpython-310.pyc | Bin 0 -> 21152 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 | 377 + .../site-packages/pip/_vendor/__init__.py | 111 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2923 bytes .../__pycache__/distro.cpython-310.pyc | Bin 0 -> 38241 bytes .../_vendor/__pycache__/six.cpython-310.pyc | Bin 0 -> 27590 bytes .../typing_extensions.cpython-310.pyc | Bin 0 -> 66586 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 651 bytes .../__pycache__/_cmd.cpython-310.pyc | Bin 0 -> 1589 bytes .../__pycache__/adapter.cpython-310.pyc | Bin 0 -> 3165 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 1855 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 765 bytes .../__pycache__/controller.cpython-310.pyc | Bin 0 -> 8219 bytes .../__pycache__/filewrapper.cpython-310.pyc | Bin 0 -> 2801 bytes .../__pycache__/heuristics.cpython-310.pyc | Bin 0 -> 4725 bytes .../__pycache__/serialize.cpython-310.pyc | Bin 0 -> 4260 bytes .../__pycache__/wrapper.cpython-310.pyc | Bin 0 -> 696 bytes .../pip/_vendor/cachecontrol/_cmd.py | 61 + .../pip/_vendor/cachecontrol/adapter.py | 137 + .../pip/_vendor/cachecontrol/cache.py | 43 + .../_vendor/cachecontrol/caches/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 302 bytes .../__pycache__/file_cache.cpython-310.pyc | Bin 0 -> 3376 bytes .../__pycache__/redis_cache.cpython-310.pyc | Bin 0 -> 1582 bytes .../_vendor/cachecontrol/caches/file_cache.py | 150 + .../cachecontrol/caches/redis_cache.py | 37 + .../pip/_vendor/cachecontrol/compat.py | 32 + .../pip/_vendor/cachecontrol/controller.py | 415 + .../pip/_vendor/cachecontrol/filewrapper.py | 111 + .../pip/_vendor/cachecontrol/heuristics.py | 139 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 33 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 284 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 463 bytes .../certifi/__pycache__/core.cpython-310.pyc | Bin 0 -> 1522 bytes .../pip/_vendor/certifi/cacert.pem | 4362 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 76 + .../pip/_vendor/chardet/__init__.py | 83 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1908 bytes .../__pycache__/big5freq.cpython-310.pyc | Bin 0 -> 27187 bytes .../__pycache__/big5prober.cpython-310.pyc | Bin 0 -> 1138 bytes .../chardistribution.cpython-310.pyc | Bin 0 -> 5748 bytes .../charsetgroupprober.cpython-310.pyc | Bin 0 -> 2237 bytes .../__pycache__/charsetprober.cpython-310.pyc | Bin 0 -> 3491 bytes .../codingstatemachine.cpython-310.pyc | Bin 0 -> 2910 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 409 bytes .../__pycache__/cp949prober.cpython-310.pyc | Bin 0 -> 1145 bytes .../chardet/__pycache__/enums.cpython-310.pyc | Bin 0 -> 2592 bytes .../__pycache__/escprober.cpython-310.pyc | Bin 0 -> 2639 bytes .../chardet/__pycache__/escsm.cpython-310.pyc | Bin 0 -> 8386 bytes .../__pycache__/eucjpprober.cpython-310.pyc | Bin 0 -> 2441 bytes .../__pycache__/euckrfreq.cpython-310.pyc | Bin 0 -> 12071 bytes .../__pycache__/euckrprober.cpython-310.pyc | Bin 0 -> 1146 bytes .../__pycache__/euctwfreq.cpython-310.pyc | Bin 0 -> 27191 bytes .../__pycache__/euctwprober.cpython-310.pyc | Bin 0 -> 1146 bytes .../__pycache__/gb2312freq.cpython-310.pyc | Bin 0 -> 19115 bytes .../__pycache__/gb2312prober.cpython-310.pyc | Bin 0 -> 1154 bytes .../__pycache__/hebrewprober.cpython-310.pyc | Bin 0 -> 3027 bytes .../__pycache__/jisfreq.cpython-310.pyc | Bin 0 -> 22143 bytes .../__pycache__/jpcntx.cpython-310.pyc | Bin 0 -> 37650 bytes .../langbulgarianmodel.cpython-310.pyc | Bin 0 -> 47931 bytes .../langgreekmodel.cpython-310.pyc | Bin 0 -> 46121 bytes .../langhebrewmodel.cpython-310.pyc | Bin 0 -> 44570 bytes .../langhungarianmodel.cpython-310.pyc | Bin 0 -> 47891 bytes .../langrussianmodel.cpython-310.pyc | Bin 0 -> 61024 bytes .../__pycache__/langthaimodel.cpython-310.pyc | Bin 0 -> 44746 bytes .../langturkishmodel.cpython-310.pyc | Bin 0 -> 44587 bytes .../__pycache__/latin1prober.cpython-310.pyc | Bin 0 -> 4437 bytes .../mbcharsetprober.cpython-310.pyc | Bin 0 -> 2256 bytes .../mbcsgroupprober.cpython-310.pyc | Bin 0 -> 1141 bytes .../__pycache__/mbcssm.cpython-310.pyc | Bin 0 -> 18768 bytes .../sbcharsetprober.cpython-310.pyc | Bin 0 -> 3087 bytes .../sbcsgroupprober.cpython-310.pyc | Bin 0 -> 1710 bytes .../__pycache__/sjisprober.cpython-310.pyc | Bin 0 -> 2479 bytes .../universaldetector.cpython-310.pyc | Bin 0 -> 5833 bytes .../__pycache__/utf8prober.cpython-310.pyc | Bin 0 -> 1990 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 447 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 107 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 204 bytes .../__pycache__/chardetect.cpython-310.pyc | Bin 0 -> 2703 bytes .../pip/_vendor/chardet/cli/chardetect.py | 84 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 36 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4398 +++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5718 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 209 bytes .../__pycache__/languages.cpython-310.pyc | Bin 0 -> 7971 bytes .../pip/_vendor/chardet/metadata/languages.py | 310 + .../pip/_vendor/chardet/sbcharsetprober.py | 145 + .../pip/_vendor/chardet/sbcsgroupprober.py | 83 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 452 bytes .../colorama/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 3013 bytes .../__pycache__/ansitowin32.cpython-310.pyc | Bin 0 -> 7911 bytes .../__pycache__/initialise.cpython-310.pyc | Bin 0 -> 1699 bytes .../__pycache__/win32.cpython-310.pyc | Bin 0 -> 3959 bytes .../__pycache__/winterm.cpython-310.pyc | Bin 0 -> 4576 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 258 + .../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 -> 1071 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 31417 bytes .../__pycache__/database.cpython-310.pyc | Bin 0 -> 42872 bytes .../distlib/__pycache__/index.cpython-310.pyc | Bin 0 -> 17326 bytes .../__pycache__/locators.cpython-310.pyc | Bin 0 -> 38385 bytes .../__pycache__/manifest.cpython-310.pyc | Bin 0 -> 10239 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 5043 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 26571 bytes .../__pycache__/resources.cpython-310.pyc | Bin 0 -> 11045 bytes .../__pycache__/scripts.cpython-310.pyc | Bin 0 -> 11261 bytes .../distlib/__pycache__/util.cpython-310.pyc | Bin 0 -> 51704 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 20158 bytes .../distlib/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 27318 bytes .../pip/_vendor/distlib/compat.py | 1116 +++ .../pip/_vendor/distlib/database.py | 1345 +++ .../pip/_vendor/distlib/index.py | 509 + .../pip/_vendor/distlib/locators.py | 1300 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 152 + .../pip/_vendor/distlib/metadata.py | 1058 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 429 + .../site-packages/pip/_vendor/distlib/util.py | 1932 ++++ .../pip/_vendor/distlib/version.py | 739 ++ .../pip/_vendor/distlib/wheel.py | 1053 ++ .../site-packages/pip/_vendor/distro.py | 1386 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1311 bytes .../__pycache__/_ihatexml.cpython-310.pyc | Bin 0 -> 13866 bytes .../__pycache__/_inputstream.cpython-310.pyc | Bin 0 -> 21683 bytes .../__pycache__/_tokenizer.cpython-310.pyc | Bin 0 -> 37329 bytes .../__pycache__/_utils.cpython-310.pyc | Bin 0 -> 4805 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 161270 bytes .../__pycache__/html5parser.cpython-310.pyc | Bin 0 -> 88480 bytes .../__pycache__/serializer.cpython-310.pyc | Bin 0 -> 10746 bytes .../pip/_vendor/html5lib/_ihatexml.py | 289 + .../pip/_vendor/html5lib/_inputstream.py | 918 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1735 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 5 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 361 bytes .../_trie/__pycache__/_base.cpython-310.pyc | Bin 0 -> 1613 bytes .../_trie/__pycache__/py.cpython-310.pyc | Bin 0 -> 2276 bytes .../pip/_vendor/html5lib/_trie/_base.py | 40 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 159 + .../pip/_vendor/html5lib/constants.py | 2946 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 209 bytes .../alphabeticalattributes.cpython-310.pyc | Bin 0 -> 1339 bytes .../filters/__pycache__/base.cpython-310.pyc | Bin 0 -> 879 bytes .../inject_meta_charset.cpython-310.pyc | Bin 0 -> 1877 bytes .../filters/__pycache__/lint.cpython-310.pyc | Bin 0 -> 2585 bytes .../__pycache__/optionaltags.cpython-310.pyc | Bin 0 -> 2736 bytes .../__pycache__/sanitizer.cpython-310.pyc | Bin 0 -> 20033 bytes .../__pycache__/whitespace.cpython-310.pyc | Bin 0 -> 1383 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 916 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2795 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 950 bytes .../__pycache__/genshi.cpython-310.pyc | Bin 0 -> 1562 bytes .../__pycache__/sax.cpython-310.pyc | Bin 0 -> 1469 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3341 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 11332 bytes .../__pycache__/dom.cpython-310.pyc | Bin 0 -> 9419 bytes .../__pycache__/etree.cpython-310.pyc | Bin 0 -> 11721 bytes .../__pycache__/etree_lxml.cpython-310.pyc | Bin 0 -> 13036 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 239 + .../_vendor/html5lib/treebuilders/etree.py | 343 + .../html5lib/treebuilders/etree_lxml.py | 392 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3991 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 6952 bytes .../__pycache__/dom.cpython-310.pyc | Bin 0 -> 1723 bytes .../__pycache__/etree.cpython-310.pyc | Bin 0 -> 3481 bytes .../__pycache__/etree_lxml.cpython-310.pyc | Bin 0 -> 6568 bytes .../__pycache__/genshi.cpython-310.pyc | Bin 0 -> 1929 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 131 + .../html5lib/treewalkers/etree_lxml.py | 215 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 856 bytes .../idna/__pycache__/codec.cpython-310.pyc | Bin 0 -> 2827 bytes .../idna/__pycache__/compat.cpython-310.pyc | Bin 0 -> 756 bytes .../idna/__pycache__/core.cpython-310.pyc | Bin 0 -> 9571 bytes .../idna/__pycache__/idnadata.cpython-310.pyc | Bin 0 -> 38234 bytes .../__pycache__/intranges.cpython-310.pyc | Bin 0 -> 1993 bytes .../__pycache__/package_data.cpython-310.pyc | Bin 0 -> 220 bytes .../__pycache__/uts46data.cpython-310.pyc | Bin 0 -> 150955 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 | 54 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1436 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 227 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 1817 bytes .../msgpack/__pycache__/ext.cpython-310.pyc | Bin 0 -> 6325 bytes .../__pycache__/fallback.cpython-310.pyc | Bin 0 -> 25454 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1012 ++ .../pip/_vendor/packaging/__about__.py | 26 + .../pip/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 599 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 455 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7309 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4621 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2714 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9296 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3984 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21536 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12199 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3584 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12934 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 -> 322 bytes .../pep517/__pycache__/build.cpython-310.pyc | Bin 0 -> 3605 bytes .../pep517/__pycache__/check.cpython-310.pyc | Bin 0 -> 4569 bytes .../__pycache__/colorlog.cpython-310.pyc | Bin 0 -> 2973 bytes .../pep517/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1546 bytes .../__pycache__/dirtools.cpython-310.pyc | Bin 0 -> 1364 bytes .../__pycache__/envbuild.cpython-310.pyc | Bin 0 -> 4387 bytes .../pep517/__pycache__/meta.cpython-310.pyc | Bin 0 -> 2969 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 12315 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 -> 930 bytes .../__pycache__/_in_process.cpython-310.pyc | Bin 0 -> 10077 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 -> 99885 bytes .../__pycache__/py31compat.cpython-310.pyc | Bin 0 -> 669 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/platformdirs/__init__.py | 331 + .../pip/_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 10485 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 1245 bytes .../__pycache__/android.cpython-310.pyc | Bin 0 -> 4277 bytes .../__pycache__/api.cpython-310.pyc | Bin 0 -> 5211 bytes .../__pycache__/macos.cpython-310.pyc | Bin 0 -> 3199 bytes .../__pycache__/unix.cpython-310.pyc | Bin 0 -> 6900 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 304 bytes .../__pycache__/windows.cpython-310.pyc | Bin 0 -> 6443 bytes .../pip/_vendor/platformdirs/android.py | 119 + .../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/progress/__init__.py | 189 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5739 bytes .../progress/__pycache__/bar.cpython-310.pyc | Bin 0 -> 2704 bytes .../__pycache__/colors.cpython-310.pyc | Bin 0 -> 1497 bytes .../__pycache__/counter.cpython-310.pyc | Bin 0 -> 1568 bytes .../__pycache__/spinner.cpython-310.pyc | Bin 0 -> 1398 bytes .../site-packages/pip/_vendor/progress/bar.py | 93 + .../pip/_vendor/progress/colors.py | 79 + .../pip/_vendor/progress/counter.py | 47 + .../pip/_vendor/progress/spinner.py | 45 + .../pip/_vendor/pygments/__init__.py | 83 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3001 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 597 bytes .../__pycache__/cmdline.cpython-310.pyc | Bin 0 -> 15460 bytes .../__pycache__/console.cpython-310.pyc | Bin 0 -> 1892 bytes .../__pycache__/filter.cpython-310.pyc | Bin 0 -> 2663 bytes .../__pycache__/formatter.cpython-310.pyc | Bin 0 -> 3019 bytes .../__pycache__/lexer.cpython-310.pyc | Bin 0 -> 24373 bytes .../__pycache__/modeline.cpython-310.pyc | Bin 0 -> 1201 bytes .../__pycache__/plugin.cpython-310.pyc | Bin 0 -> 2053 bytes .../__pycache__/regexopt.cpython-310.pyc | Bin 0 -> 2965 bytes .../__pycache__/scanner.cpython-310.pyc | Bin 0 -> 3566 bytes .../__pycache__/sphinxext.cpython-310.pyc | Bin 0 -> 4551 bytes .../__pycache__/style.cpython-310.pyc | Bin 0 -> 4588 bytes .../__pycache__/token.cpython-310.pyc | Bin 0 -> 4660 bytes .../__pycache__/unistring.cpython-310.pyc | Bin 0 -> 31214 bytes .../pygments/__pycache__/util.cpython-310.pyc | Bin 0 -> 9171 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 -> 29522 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 153 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4677 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 5544 bytes .../__pycache__/bbcode.cpython-310.pyc | Bin 0 -> 3094 bytes .../__pycache__/groff.cpython-310.pyc | Bin 0 -> 4367 bytes .../__pycache__/html.cpython-310.pyc | Bin 0 -> 29078 bytes .../__pycache__/img.cpython-310.pyc | Bin 0 -> 17506 bytes .../__pycache__/irc.cpython-310.pyc | Bin 0 -> 4597 bytes .../__pycache__/latex.cpython-310.pyc | Bin 0 -> 13503 bytes .../__pycache__/other.cpython-310.pyc | Bin 0 -> 4813 bytes .../__pycache__/pangomarkup.cpython-310.pyc | Bin 0 -> 2113 bytes .../__pycache__/rtf.cpython-310.pyc | Bin 0 -> 4143 bytes .../__pycache__/svg.cpython-310.pyc | Bin 0 -> 6341 bytes .../__pycache__/terminal.cpython-310.pyc | Bin 0 -> 4008 bytes .../__pycache__/terminal256.cpython-310.pyc | Bin 0 -> 9258 bytes .../_vendor/pygments/formatters/_mapping.py | 84 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 168 + .../pip/_vendor/pygments/formatters/html.py | 983 ++ .../pip/_vendor/pygments/formatters/img.py | 641 ++ .../pip/_vendor/pygments/formatters/irc.py | 179 + .../pip/_vendor/pygments/formatters/latex.py | 511 + .../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 | 879 ++ .../pip/_vendor/pygments/lexers/__init__.py | 341 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9193 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 58131 bytes .../lexers/__pycache__/python.cpython-310.pyc | Bin 0 -> 29392 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 580 ++ .../pip/_vendor/pygments/lexers/python.py | 1188 +++ .../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 -> 3229 bytes .../pip/_vendor/pygments/token.py | 212 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 308 + .../pip/_vendor/pyparsing/__init__.py | 328 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7134 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7191 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10114 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 175244 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9081 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 34776 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24788 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12109 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 9823 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8614 bytes .../pip/_vendor/pyparsing/actions.py | 207 + .../pip/_vendor/pyparsing/common.py | 424 + .../pip/_vendor/pyparsing/core.py | 5789 +++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 593 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 15654 bytes .../pip/_vendor/pyparsing/exceptions.py | 267 + .../pip/_vendor/pyparsing/helpers.py | 1069 +++ .../pip/_vendor/pyparsing/results.py | 760 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 332 + .../pip/_vendor/pyparsing/util.py | 235 + .../pip/_vendor/requests/__init__.py | 154 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4047 bytes .../__pycache__/__version__.cpython-310.pyc | Bin 0 -> 564 bytes .../_internal_utils.cpython-310.pyc | Bin 0 -> 1316 bytes .../__pycache__/adapters.cpython-310.pyc | Bin 0 -> 17052 bytes .../requests/__pycache__/api.cpython-310.pyc | Bin 0 -> 6663 bytes .../requests/__pycache__/auth.cpython-310.pyc | Bin 0 -> 8106 bytes .../__pycache__/certs.cpython-310.pyc | Bin 0 -> 648 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 1683 bytes .../__pycache__/cookies.cpython-310.pyc | Bin 0 -> 18696 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5257 bytes .../requests/__pycache__/help.cpython-310.pyc | Bin 0 -> 2916 bytes .../__pycache__/hooks.cpython-310.pyc | Bin 0 -> 1003 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 24322 bytes .../__pycache__/packages.cpython-310.pyc | Bin 0 -> 517 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 19630 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 4680 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 4462 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 24405 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 538 ++ .../site-packages/pip/_vendor/requests/api.py | 159 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 77 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 133 + .../pip/_vendor/requests/help.py | 132 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 973 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 771 ++ .../pip/_vendor/requests/status_codes.py | 123 + .../pip/_vendor/requests/structures.py | 105 + .../pip/_vendor/requests/utils.py | 1060 ++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 615 bytes .../__pycache__/providers.cpython-310.pyc | Bin 0 -> 6666 bytes .../__pycache__/reporters.cpython-310.pyc | Bin 0 -> 2586 bytes .../__pycache__/resolvers.cpython-310.pyc | Bin 0 -> 15139 bytes .../__pycache__/structs.cpython-310.pyc | Bin 0 -> 7172 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 210 bytes .../collections_abc.cpython-310.pyc | Bin 0 -> 386 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 | 172 + .../pip/_vendor/rich/__main__.py | 280 + .../rich/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5900 bytes .../rich/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 7334 bytes .../__pycache__/_cell_widths.cpython-310.pyc | Bin 0 -> 7823 bytes .../__pycache__/_emoji_codes.cpython-310.pyc | Bin 0 -> 360063 bytes .../_emoji_replace.cpython-310.pyc | Bin 0 -> 1203 bytes .../__pycache__/_extension.cpython-310.pyc | Bin 0 -> 504 bytes .../rich/__pycache__/_inspect.cpython-310.pyc | Bin 0 -> 6621 bytes .../__pycache__/_log_render.cpython-310.pyc | Bin 0 -> 2649 bytes .../rich/__pycache__/_loop.cpython-310.pyc | Bin 0 -> 1301 bytes .../__pycache__/_lru_cache.cpython-310.pyc | Bin 0 -> 1584 bytes .../__pycache__/_palettes.cpython-310.pyc | Bin 0 -> 5106 bytes .../rich/__pycache__/_pick.cpython-310.pyc | Bin 0 -> 649 bytes .../rich/__pycache__/_ratio.cpython-310.pyc | Bin 0 -> 5166 bytes .../__pycache__/_spinners.cpython-310.pyc | Bin 0 -> 15222 bytes .../rich/__pycache__/_stack.cpython-310.pyc | Bin 0 -> 847 bytes .../rich/__pycache__/_timer.cpython-310.pyc | Bin 0 -> 696 bytes .../rich/__pycache__/_windows.cpython-310.pyc | Bin 0 -> 1887 bytes .../rich/__pycache__/_wrap.cpython-310.pyc | Bin 0 -> 1525 bytes .../rich/__pycache__/abc.cpython-310.pyc | Bin 0 -> 1323 bytes .../rich/__pycache__/align.cpython-310.pyc | Bin 0 -> 7977 bytes .../rich/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 6026 bytes .../rich/__pycache__/bar.cpython-310.pyc | Bin 0 -> 2992 bytes .../rich/__pycache__/box.cpython-310.pyc | Bin 0 -> 7766 bytes .../rich/__pycache__/cells.cpython-310.pyc | Bin 0 -> 3508 bytes .../rich/__pycache__/color.cpython-310.pyc | Bin 0 -> 16764 bytes .../__pycache__/color_triplet.cpython-310.pyc | Bin 0 -> 1446 bytes .../rich/__pycache__/columns.cpython-310.pyc | Bin 0 -> 6206 bytes .../rich/__pycache__/console.cpython-310.pyc | Bin 0 -> 70451 bytes .../__pycache__/constrain.cpython-310.pyc | Bin 0 -> 1763 bytes .../__pycache__/containers.cpython-310.pyc | Bin 0 -> 6495 bytes .../rich/__pycache__/control.cpython-310.pyc | Bin 0 -> 6838 bytes .../default_styles.cpython-310.pyc | Bin 0 -> 6038 bytes .../rich/__pycache__/diagnose.cpython-310.pyc | Bin 0 -> 364 bytes .../rich/__pycache__/emoji.cpython-310.pyc | Bin 0 -> 3276 bytes .../rich/__pycache__/errors.cpython-310.pyc | Bin 0 -> 1536 bytes .../__pycache__/file_proxy.cpython-310.pyc | Bin 0 -> 2273 bytes .../rich/__pycache__/filesize.cpython-310.pyc | Bin 0 -> 2625 bytes .../__pycache__/highlighter.cpython-310.pyc | Bin 0 -> 5352 bytes .../rich/__pycache__/json.cpython-310.pyc | Bin 0 -> 4756 bytes .../rich/__pycache__/jupyter.cpython-310.pyc | Bin 0 -> 3835 bytes .../rich/__pycache__/layout.cpython-310.pyc | Bin 0 -> 14687 bytes .../rich/__pycache__/live.cpython-310.pyc | Bin 0 -> 11577 bytes .../__pycache__/live_render.cpython-310.pyc | Bin 0 -> 3411 bytes .../rich/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9303 bytes .../rich/__pycache__/markup.cpython-310.pyc | Bin 0 -> 5922 bytes .../rich/__pycache__/measure.cpython-310.pyc | Bin 0 -> 5067 bytes .../rich/__pycache__/padding.cpython-310.pyc | Bin 0 -> 4491 bytes .../rich/__pycache__/pager.cpython-310.pyc | Bin 0 -> 1504 bytes .../rich/__pycache__/palette.cpython-310.pyc | Bin 0 -> 3717 bytes .../rich/__pycache__/panel.cpython-310.pyc | Bin 0 -> 6400 bytes .../rich/__pycache__/pretty.cpython-310.pyc | Bin 0 -> 25112 bytes .../rich/__pycache__/progress.cpython-310.pyc | Bin 0 -> 33340 bytes .../__pycache__/progress_bar.cpython-310.pyc | Bin 0 -> 6716 bytes .../rich/__pycache__/prompt.cpython-310.pyc | Bin 0 -> 11308 bytes .../rich/__pycache__/protocol.cpython-310.pyc | Bin 0 -> 1380 bytes .../rich/__pycache__/region.cpython-310.pyc | Bin 0 -> 536 bytes .../rich/__pycache__/repr.cpython-310.pyc | Bin 0 -> 4049 bytes .../rich/__pycache__/rule.cpython-310.pyc | Bin 0 -> 3746 bytes .../rich/__pycache__/scope.cpython-310.pyc | Bin 0 -> 2997 bytes .../rich/__pycache__/screen.cpython-310.pyc | Bin 0 -> 1888 bytes .../rich/__pycache__/segment.cpython-310.pyc | Bin 0 -> 20578 bytes .../rich/__pycache__/spinner.cpython-310.pyc | Bin 0 -> 4408 bytes .../rich/__pycache__/status.cpython-310.pyc | Bin 0 -> 4602 bytes .../rich/__pycache__/style.cpython-310.pyc | Bin 0 -> 20531 bytes .../rich/__pycache__/styled.cpython-310.pyc | Bin 0 -> 1772 bytes .../rich/__pycache__/syntax.cpython-310.pyc | Bin 0 -> 19045 bytes .../rich/__pycache__/table.cpython-310.pyc | Bin 0 -> 26983 bytes .../rich/__pycache__/tabulate.cpython-310.pyc | Bin 0 -> 1765 bytes .../terminal_theme.cpython-310.pyc | Bin 0 -> 1729 bytes .../rich/__pycache__/text.cpython-310.pyc | Bin 0 -> 39293 bytes .../rich/__pycache__/theme.cpython-310.pyc | Bin 0 -> 4709 bytes .../rich/__pycache__/themes.cpython-310.pyc | Bin 0 -> 302 bytes .../__pycache__/traceback.cpython-310.pyc | Bin 0 -> 19546 bytes .../rich/__pycache__/tree.cpython-310.pyc | Bin 0 -> 7326 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/_extension.py | 10 + .../pip/_vendor/rich/_inspect.py | 210 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_lru_cache.py | 34 + .../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 | 848 ++ .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_windows.py | 72 + .../site-packages/pip/_vendor/rich/_wrap.py | 55 + .../site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 312 + .../site-packages/pip/_vendor/rich/ansi.py | 228 + .../site-packages/pip/_vendor/rich/bar.py | 94 + .../site-packages/pip/_vendor/rich/box.py | 483 + .../site-packages/pip/_vendor/rich/cells.py | 147 + .../site-packages/pip/_vendor/rich/color.py | 581 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2211 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 175 + .../pip/_vendor/rich/default_styles.py | 183 + .../pip/_vendor/rich/diagnose.py | 6 + .../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 | 147 + .../site-packages/pip/_vendor/rich/json.py | 140 + .../site-packages/pip/_vendor/rich/jupyter.py | 92 + .../site-packages/pip/_vendor/rich/layout.py | 444 + .../site-packages/pip/_vendor/rich/live.py | 365 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 268 + .../site-packages/pip/_vendor/rich/markup.py | 244 + .../site-packages/pip/_vendor/rich/measure.py | 149 + .../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 | 250 + .../site-packages/pip/_vendor/rich/pretty.py | 903 ++ .../pip/_vendor/rich/progress.py | 1036 ++ .../pip/_vendor/rich/progress_bar.py | 216 + .../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 | 151 + .../site-packages/pip/_vendor/rich/rule.py | 115 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 720 ++ .../site-packages/pip/_vendor/rich/spinner.py | 134 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 785 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 735 ++ .../site-packages/pip/_vendor/rich/table.py | 968 ++ .../pip/_vendor/rich/tabulate.py | 51 + .../pip/_vendor/rich/terminal_theme.py | 55 + .../site-packages/pip/_vendor/rich/text.py | 1282 +++ .../site-packages/pip/_vendor/rich/theme.py | 112 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 678 ++ .../site-packages/pip/_vendor/rich/tree.py | 249 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 517 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16383 bytes .../__pycache__/_asyncio.cpython-310.pyc | Bin 0 -> 2623 bytes .../__pycache__/_utils.cpython-310.pyc | Bin 0 -> 1236 bytes .../__pycache__/after.cpython-310.pyc | Bin 0 -> 1240 bytes .../__pycache__/before.cpython-310.pyc | Bin 0 -> 1118 bytes .../__pycache__/before_sleep.cpython-310.pyc | Bin 0 -> 1420 bytes .../tenacity/__pycache__/nap.cpython-310.pyc | Bin 0 -> 1208 bytes .../__pycache__/retry.cpython-310.pyc | Bin 0 -> 8438 bytes .../tenacity/__pycache__/stop.cpython-310.pyc | Bin 0 -> 4026 bytes .../__pycache__/tornadoweb.cpython-310.pyc | Bin 0 -> 1773 bytes .../tenacity/__pycache__/wait.cpython-310.pyc | Bin 0 -> 7970 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 | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 388 bytes .../tomli/__pycache__/_parser.cpython-310.pyc | Bin 0 -> 16342 bytes .../tomli/__pycache__/_re.cpython-310.pyc | Bin 0 -> 2432 bytes .../pip/_vendor/tomli/_parser.py | 703 ++ .../site-packages/pip/_vendor/tomli/_re.py | 83 + .../pip/_vendor/typing_extensions.py | 2296 +++++ .../pip/_vendor/urllib3/__init__.py | 85 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2198 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 11363 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 222 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 13645 bytes .../connectionpool.cpython-310.pyc | Bin 0 -> 25487 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 11003 bytes .../__pycache__/fields.cpython-310.pyc | Bin 0 -> 8192 bytes .../__pycache__/filepost.cpython-310.pyc | Bin 0 -> 2759 bytes .../__pycache__/poolmanager.cpython-310.pyc | Bin 0 -> 15307 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 5635 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 20926 bytes .../pip/_vendor/urllib3/_collections.py | 355 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 569 ++ .../pip/_vendor/urllib3/connectionpool.py | 1113 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 208 bytes .../_appengine_environ.cpython-310.pyc | Bin 0 -> 1388 bytes .../__pycache__/appengine.cpython-310.pyc | Bin 0 -> 8204 bytes .../__pycache__/ntlmpool.cpython-310.pyc | Bin 0 -> 3643 bytes .../__pycache__/pyopenssl.cpython-310.pyc | Bin 0 -> 15545 bytes .../securetransport.cpython-310.pyc | Bin 0 -> 21950 bytes .../contrib/__pycache__/socks.cpython-310.pyc | Bin 0 -> 5610 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 225 bytes .../__pycache__/bindings.cpython-310.pyc | Bin 0 -> 10721 bytes .../__pycache__/low_level.cpython-310.pyc | Bin 0 -> 9108 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 | 511 + .../urllib3/contrib/securetransport.py | 922 ++ .../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 -> 209 bytes .../packages/__pycache__/six.cpython-310.pyc | Bin 0 -> 27663 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 219 bytes .../__pycache__/makefile.cpython-310.pyc | Bin 0 -> 1319 bytes .../urllib3/packages/backports/makefile.py | 51 + .../pip/_vendor/urllib3/packages/six.py | 1077 +++ .../pip/_vendor/urllib3/poolmanager.py | 539 ++ .../pip/_vendor/urllib3/request.py | 170 + .../pip/_vendor/urllib3/response.py | 821 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1118 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 3446 bytes .../util/__pycache__/proxy.cpython-310.pyc | Bin 0 -> 1351 bytes .../util/__pycache__/queue.cpython-310.pyc | Bin 0 -> 1073 bytes .../util/__pycache__/request.cpython-310.pyc | Bin 0 -> 3481 bytes .../util/__pycache__/response.cpython-310.pyc | Bin 0 -> 2366 bytes .../util/__pycache__/retry.cpython-310.pyc | Bin 0 -> 16161 bytes .../util/__pycache__/ssl_.cpython-310.pyc | Bin 0 -> 11318 bytes .../ssl_match_hostname.cpython-310.pyc | Bin 0 -> 3290 bytes .../__pycache__/ssltransport.cpython-310.pyc | Bin 0 -> 7408 bytes .../util/__pycache__/timeout.cpython-310.pyc | Bin 0 -> 8942 bytes .../util/__pycache__/url.cpython-310.pyc | Bin 0 -> 10687 bytes .../util/__pycache__/wait.cpython-310.pyc | Bin 0 -> 3102 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 | 143 + .../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 | 161 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 268 + .../pip/_vendor/urllib3/util/url.py | 432 + .../pip/_vendor/urllib3/util/wait.py | 153 + .../site-packages/pip/_vendor/vendor.txt | 25 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9755 bytes .../__pycache__/labels.cpython-310.pyc | Bin 0 -> 5245 bytes .../__pycache__/mklabels.cpython-310.pyc | Bin 0 -> 1950 bytes .../__pycache__/tests.cpython-310.pyc | Bin 0 -> 5052 bytes .../x_user_defined.cpython-310.pyc | Bin 0 -> 2601 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 + env/lib/python3.10/site-packages/pip/py.typed | 4 + .../site-packages/pkg_resources/__init__.py | 3303 +++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 100610 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 202 bytes .../__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 20263 bytes .../__pycache__/pyparsing.cpython-310.pyc | Bin 0 -> 198755 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 26 + .../_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 609 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 465 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7319 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4631 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2989 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9315 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 4003 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 22207 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12233 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3594 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12944 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 67 + .../_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 828 ++ .../pkg_resources/_vendor/packaging/tags.py | 484 + .../pkg_resources/_vendor/packaging/utils.py | 136 + .../_vendor/packaging/version.py | 504 + .../pkg_resources/_vendor/pyparsing.py | 5742 +++++++++++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2910 bytes .../__pycache__/setup.cpython-310.pyc | Bin 0 -> 330 bytes .../data/my-test-package-source/setup.py | 6 + .../setuptools-59.6.0.dist-info/INSTALLER | 1 + .../setuptools-59.6.0.dist-info/LICENSE | 19 + .../setuptools-59.6.0.dist-info/METADATA | 124 + .../setuptools-59.6.0.dist-info/RECORD | 298 + .../setuptools-59.6.0.dist-info/REQUESTED | 0 .../setuptools-59.6.0.dist-info/WHEEL | 5 + .../entry_points.txt | 56 + .../setuptools-59.6.0.dist-info/top_level.txt | 4 + .../site-packages/setuptools/__init__.py | 242 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 8606 bytes .../_deprecation_warning.cpython-310.pyc | Bin 0 -> 563 bytes .../__pycache__/_imp.cpython-310.pyc | Bin 0 -> 2089 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 5859 bytes .../__pycache__/build_meta.cpython-310.pyc | Bin 0 -> 9473 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 20942 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 870 bytes .../__pycache__/depends.cpython-310.pyc | Bin 0 -> 5309 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 36350 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 1515 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 1959 bytes .../__pycache__/glob.cpython-310.pyc | Bin 0 -> 3748 bytes .../__pycache__/installer.cpython-310.pyc | Bin 0 -> 2994 bytes .../__pycache__/launch.cpython-310.pyc | Bin 0 -> 920 bytes .../__pycache__/monkey.cpython-310.pyc | Bin 0 -> 4648 bytes .../__pycache__/msvc.cpython-310.pyc | Bin 0 -> 42652 bytes .../__pycache__/namespaces.cpython-310.pyc | Bin 0 -> 3631 bytes .../__pycache__/package_index.cpython-310.pyc | Bin 0 -> 32744 bytes .../__pycache__/py34compat.cpython-310.pyc | Bin 0 -> 495 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 15771 bytes .../__pycache__/unicode_utils.cpython-310.pyc | Bin 0 -> 1125 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 337 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 7363 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 -> 571 bytes .../__pycache__/_msvccompiler.cpython-310.pyc | Bin 0 -> 13848 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 6576 bytes .../__pycache__/bcppcompiler.cpython-310.pyc | Bin 0 -> 6563 bytes .../__pycache__/ccompiler.cpython-310.pyc | Bin 0 -> 33320 bytes .../__pycache__/cmd.cpython-310.pyc | Bin 0 -> 13963 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 3602 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 7103 bytes .../cygwinccompiler.cpython-310.pyc | Bin 0 -> 9010 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 265 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 2786 bytes .../__pycache__/dir_util.cpython-310.pyc | Bin 0 -> 5897 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 34062 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 5007 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 7021 bytes .../__pycache__/fancy_getopt.cpython-310.pyc | Bin 0 -> 10645 bytes .../__pycache__/file_util.cpython-310.pyc | Bin 0 -> 5991 bytes .../__pycache__/filelist.cpython-310.pyc | Bin 0 -> 10837 bytes .../__pycache__/log.cpython-310.pyc | Bin 0 -> 2322 bytes .../__pycache__/msvc9compiler.cpython-310.pyc | Bin 0 -> 17577 bytes .../__pycache__/msvccompiler.cpython-310.pyc | Bin 0 -> 14796 bytes .../__pycache__/py35compat.cpython-310.pyc | Bin 0 -> 641 bytes .../__pycache__/py38compat.cpython-310.pyc | Bin 0 -> 438 bytes .../__pycache__/spawn.cpython-310.pyc | Bin 0 -> 2908 bytes .../__pycache__/sysconfig.cpython-310.pyc | Bin 0 -> 12889 bytes .../__pycache__/text_file.cpython-310.pyc | Bin 0 -> 8484 bytes .../__pycache__/unixccompiler.cpython-310.pyc | Bin 0 -> 6816 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 14757 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 7858 bytes .../versionpredicate.cpython-310.pyc | Bin 0 -> 5351 bytes .../setuptools/_distutils/_msvccompiler.py | 561 ++ .../setuptools/_distutils/archive_util.py | 256 + .../setuptools/_distutils/bcppcompiler.py | 393 + .../setuptools/_distutils/ccompiler.py | 1123 +++ .../setuptools/_distutils/cmd.py | 403 + .../setuptools/_distutils/command/__init__.py | 31 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 544 bytes .../command/__pycache__/bdist.cpython-310.pyc | Bin 0 -> 3678 bytes .../__pycache__/bdist_dumb.cpython-310.pyc | Bin 0 -> 3657 bytes .../__pycache__/bdist_msi.cpython-310.pyc | Bin 0 -> 19733 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 12301 bytes .../__pycache__/bdist_wininst.cpython-310.pyc | Bin 0 -> 8644 bytes .../command/__pycache__/build.cpython-310.pyc | Bin 0 -> 3906 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 4883 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 16231 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 9902 bytes .../__pycache__/build_scripts.cpython-310.pyc | Bin 0 -> 4025 bytes .../command/__pycache__/check.cpython-310.pyc | Bin 0 -> 5022 bytes .../command/__pycache__/clean.cpython-310.pyc | Bin 0 -> 2161 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 10343 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 15281 bytes .../__pycache__/install_data.cpython-310.pyc | Bin 0 -> 2360 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 3325 bytes .../install_headers.cpython-310.pyc | Bin 0 -> 1783 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 5185 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2212 bytes .../__pycache__/py37compat.cpython-310.pyc | Bin 0 -> 1053 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 8696 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 14512 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 5388 bytes .../setuptools/_distutils/command/bdist.py | 143 + .../_distutils/command/bdist_dumb.py | 123 + .../_distutils/command/bdist_msi.py | 749 ++ .../_distutils/command/bdist_rpm.py | 579 ++ .../_distutils/command/bdist_wininst.py | 377 + .../setuptools/_distutils/command/build.py | 157 + .../_distutils/command/build_clib.py | 209 + .../_distutils/command/build_ext.py | 755 ++ .../setuptools/_distutils/command/build_py.py | 392 + .../_distutils/command/build_scripts.py | 152 + .../setuptools/_distutils/command/check.py | 148 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 344 + .../setuptools/_distutils/command/install.py | 721 ++ .../_distutils/command/install_data.py | 79 + .../_distutils/command/install_egg_info.py | 84 + .../_distutils/command/install_headers.py | 47 + .../_distutils/command/install_lib.py | 217 + .../_distutils/command/install_scripts.py | 60 + .../_distutils/command/py37compat.py | 30 + .../setuptools/_distutils/command/register.py | 304 + .../setuptools/_distutils/command/sdist.py | 494 + .../setuptools/_distutils/command/upload.py | 214 + .../setuptools/_distutils/config.py | 130 + .../setuptools/_distutils/core.py | 249 + .../setuptools/_distutils/cygwinccompiler.py | 425 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 92 + .../setuptools/_distutils/dir_util.py | 210 + .../setuptools/_distutils/dist.py | 1257 +++ .../setuptools/_distutils/errors.py | 97 + .../setuptools/_distutils/extension.py | 240 + .../setuptools/_distutils/fancy_getopt.py | 457 + .../setuptools/_distutils/file_util.py | 238 + .../setuptools/_distutils/filelist.py | 355 + .../setuptools/_distutils/log.py | 77 + .../setuptools/_distutils/msvc9compiler.py | 788 ++ .../setuptools/_distutils/msvccompiler.py | 643 ++ .../setuptools/_distutils/py35compat.py | 19 + .../setuptools/_distutils/py38compat.py | 7 + .../setuptools/_distutils/spawn.py | 106 + .../setuptools/_distutils/sysconfig.py | 601 ++ .../setuptools/_distutils/text_file.py | 286 + .../setuptools/_distutils/unixccompiler.py | 325 + .../setuptools/_distutils/util.py | 548 ++ .../setuptools/_distutils/version.py | 363 + .../setuptools/_distutils/versionpredicate.py | 169 + .../site-packages/setuptools/_imp.py | 82 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 199 bytes .../__pycache__/ordered_set.cpython-310.pyc | Bin 0 -> 16335 bytes .../__pycache__/pyparsing.cpython-310.pyc | Bin 0 -> 198752 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 280 bytes .../__pycache__/more.cpython-310.pyc | Bin 0 -> 109998 bytes .../__pycache__/recipes.cpython-310.pyc | Bin 0 -> 17980 bytes .../setuptools/_vendor/more_itertools/more.py | 3825 ++++++++ .../_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 -> 606 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 462 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7316 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4628 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2986 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9309 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3997 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 22204 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12230 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3591 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12941 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 67 + .../setuptools/_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 828 ++ .../setuptools/_vendor/packaging/tags.py | 484 + .../setuptools/_vendor/packaging/utils.py | 136 + .../setuptools/_vendor/packaging/version.py | 504 + .../setuptools/_vendor/pyparsing.py | 5742 +++++++++++ .../site-packages/setuptools/archive_util.py | 205 + .../site-packages/setuptools/build_meta.py | 290 + .../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 -> 388 bytes .../command/__pycache__/alias.cpython-310.pyc | Bin 0 -> 2390 bytes .../__pycache__/bdist_egg.cpython-310.pyc | Bin 0 -> 13116 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 1603 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 2477 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 9906 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 8279 bytes .../__pycache__/develop.cpython-310.pyc | Bin 0 -> 6166 bytes .../__pycache__/dist_info.cpython-310.pyc | Bin 0 -> 1408 bytes .../__pycache__/easy_install.cpython-310.pyc | Bin 0 -> 65185 bytes .../__pycache__/egg_info.cpython-310.pyc | Bin 0 -> 22764 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 4214 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 2939 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 5154 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2443 bytes .../__pycache__/py36compat.cpython-310.pyc | Bin 0 -> 4550 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 854 bytes .../__pycache__/rotate.cpython-310.pyc | Bin 0 -> 2521 bytes .../__pycache__/saveopts.cpython-310.pyc | Bin 0 -> 940 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 6969 bytes .../__pycache__/setopt.cpython-310.pyc | Bin 0 -> 4702 bytes .../command/__pycache__/test.cpython-310.pyc | Bin 0 -> 8146 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 827 bytes .../__pycache__/upload_docs.cpython-310.pyc | Bin 0 -> 6196 bytes .../site-packages/setuptools/command/alias.py | 78 + .../setuptools/command/bdist_egg.py | 456 + .../setuptools/command/bdist_rpm.py | 40 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_py.py | 242 + .../setuptools/command/develop.py | 193 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2354 +++++ .../setuptools/command/egg_info.py | 755 ++ .../setuptools/command/install.py | 132 + .../setuptools/command/install_egg_info.py | 82 + .../setuptools/command/install_lib.py | 148 + .../setuptools/command/install_scripts.py | 69 + .../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 | 252 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 202 + .../site-packages/setuptools/config.py | 751 ++ .../site-packages/setuptools/dep_util.py | 25 + .../site-packages/setuptools/depends.py | 176 + .../site-packages/setuptools/dist.py | 1156 +++ .../site-packages/setuptools/errors.py | 40 + .../site-packages/setuptools/extension.py | 55 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2949 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/monkey.py | 177 + .../site-packages/setuptools/msvc.py | 1805 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1127 +++ .../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 + .../werkzeug-3.0.1.dist-info/INSTALLER | 1 + .../werkzeug-3.0.1.dist-info/LICENSE.rst | 28 + .../werkzeug-3.0.1.dist-info/METADATA | 118 + .../werkzeug-3.0.1.dist-info/RECORD | 126 + .../werkzeug-3.0.1.dist-info/REQUESTED | 0 .../werkzeug-3.0.1.dist-info/WHEEL | 4 + .../site-packages/werkzeug/__init__.py | 25 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 947 bytes .../__pycache__/_internal.cpython-310.pyc | Bin 0 -> 7069 bytes .../__pycache__/_reloader.cpython-310.pyc | Bin 0 -> 12639 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 27339 bytes .../__pycache__/formparser.cpython-310.pyc | Bin 0 -> 12661 bytes .../werkzeug/__pycache__/http.cpython-310.pyc | Bin 0 -> 38904 bytes .../__pycache__/local.cpython-310.pyc | Bin 0 -> 20935 bytes .../__pycache__/security.cpython-310.pyc | Bin 0 -> 5366 bytes .../__pycache__/serving.cpython-310.pyc | Bin 0 -> 30462 bytes .../werkzeug/__pycache__/test.cpython-310.pyc | Bin 0 -> 42904 bytes .../__pycache__/testapp.cpython-310.pyc | Bin 0 -> 6408 bytes .../werkzeug/__pycache__/urls.cpython-310.pyc | Bin 0 -> 6460 bytes .../__pycache__/user_agent.cpython-310.pyc | Bin 0 -> 1875 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 22293 bytes .../werkzeug/__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 19967 bytes .../site-packages/werkzeug/_internal.py | 214 + .../site-packages/werkzeug/_reloader.py | 458 + .../werkzeug/datastructures/__init__.py | 34 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1569 bytes .../__pycache__/accept.cpython-310.pyc | Bin 0 -> 10661 bytes .../__pycache__/auth.cpython-310.pyc | Bin 0 -> 10484 bytes .../__pycache__/cache_control.cpython-310.pyc | Bin 0 -> 6628 bytes .../__pycache__/csp.cpython-310.pyc | Bin 0 -> 4164 bytes .../__pycache__/etag.cpython-310.pyc | Bin 0 -> 3928 bytes .../__pycache__/file_storage.cpython-310.pyc | Bin 0 -> 6077 bytes .../__pycache__/headers.cpython-310.pyc | Bin 0 -> 17769 bytes .../__pycache__/mixins.cpython-310.pyc | Bin 0 -> 9064 bytes .../__pycache__/range.cpython-310.pyc | Bin 0 -> 6031 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 35948 bytes .../werkzeug/datastructures/accept.py | 326 + .../werkzeug/datastructures/accept.pyi | 54 + .../werkzeug/datastructures/auth.py | 318 + .../werkzeug/datastructures/cache_control.py | 175 + .../werkzeug/datastructures/cache_control.pyi | 109 + .../werkzeug/datastructures/csp.py | 94 + .../werkzeug/datastructures/csp.pyi | 169 + .../werkzeug/datastructures/etag.py | 95 + .../werkzeug/datastructures/etag.pyi | 30 + .../werkzeug/datastructures/file_storage.py | 196 + .../werkzeug/datastructures/file_storage.pyi | 47 + .../werkzeug/datastructures/headers.py | 515 + .../werkzeug/datastructures/headers.pyi | 109 + .../werkzeug/datastructures/mixins.py | 242 + .../werkzeug/datastructures/mixins.pyi | 97 + .../werkzeug/datastructures/range.py | 180 + .../werkzeug/datastructures/range.pyi | 57 + .../werkzeug/datastructures/structures.py | 1006 ++ .../werkzeug/datastructures/structures.pyi | 208 + .../site-packages/werkzeug/debug/__init__.py | 534 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 14379 bytes .../debug/__pycache__/console.cpython-310.pyc | Bin 0 -> 8333 bytes .../debug/__pycache__/repr.cpython-310.pyc | Bin 0 -> 9084 bytes .../debug/__pycache__/tbtools.cpython-310.pyc | Bin 0 -> 11815 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../site-packages/werkzeug/debug/repr.py | 283 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 360 + .../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 | 437 + .../site-packages/werkzeug/exceptions.py | 879 ++ .../site-packages/werkzeug/formparser.py | 421 + .../python3.10/site-packages/werkzeug/http.py | 1372 +++ .../site-packages/werkzeug/local.py | 643 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 200 bytes .../__pycache__/dispatcher.cpython-310.pyc | Bin 0 -> 2849 bytes .../__pycache__/http_proxy.cpython-310.pyc | Bin 0 -> 6942 bytes .../__pycache__/lint.cpython-310.pyc | Bin 0 -> 13003 bytes .../__pycache__/profiler.cpython-310.pyc | Bin 0 -> 5641 bytes .../__pycache__/proxy_fix.cpython-310.pyc | Bin 0 -> 6042 bytes .../__pycache__/shared_data.cpython-310.pyc | Bin 0 -> 9294 bytes .../werkzeug/middleware/dispatcher.py | 80 + .../werkzeug/middleware/http_proxy.py | 235 + .../site-packages/werkzeug/middleware/lint.py | 420 + .../werkzeug/middleware/profiler.py | 154 + .../werkzeug/middleware/proxy_fix.py | 182 + .../werkzeug/middleware/shared_data.py | 282 + .../site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 133 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4638 bytes .../__pycache__/converters.cpython-310.pyc | Bin 0 -> 9165 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5650 bytes .../routing/__pycache__/map.cpython-310.pyc | Bin 0 -> 30940 bytes .../__pycache__/matcher.cpython-310.pyc | Bin 0 -> 5143 bytes .../routing/__pycache__/rules.cpython-310.pyc | Bin 0 -> 27673 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 148 + .../site-packages/werkzeug/routing/map.py | 946 ++ .../site-packages/werkzeug/routing/matcher.py | 202 + .../site-packages/werkzeug/routing/rules.py | 909 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 196 bytes .../sansio/__pycache__/http.cpython-310.pyc | Bin 0 -> 4146 bytes .../__pycache__/multipart.cpython-310.pyc | Bin 0 -> 7506 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 17311 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 24530 bytes .../sansio/__pycache__/utils.cpython-310.pyc | Bin 0 -> 4635 bytes .../site-packages/werkzeug/sansio/http.py | 171 + .../werkzeug/sansio/multipart.py | 321 + .../site-packages/werkzeug/sansio/request.py | 536 ++ .../site-packages/werkzeug/sansio/response.py | 751 ++ .../site-packages/werkzeug/sansio/utils.py | 159 + .../site-packages/werkzeug/security.py | 157 + .../site-packages/werkzeug/serving.py | 1109 +++ .../python3.10/site-packages/werkzeug/test.py | 1462 +++ .../site-packages/werkzeug/testapp.py | 181 + .../python3.10/site-packages/werkzeug/urls.py | 216 + .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/utils.py | 690 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 315 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 21663 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 28433 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 835 ++ .../python3.10/site-packages/werkzeug/wsgi.py | 595 ++ env/lib64 | 1 + env/pyvenv.cfg | 3 + static/css/style.css | 20 +- static/js/script.js | 74 +- templates/base.html | 23 +- templates/second_page.html | 31 + 1686 files changed, 305951 insertions(+), 32 deletions(-) create mode 100644 __pycache__/app.cpython-310.pyc create mode 100644 env/bin/Activate.ps1 create mode 100644 env/bin/activate create mode 100644 env/bin/activate.csh create mode 100644 env/bin/activate.fish create mode 100755 env/bin/flask create mode 100755 env/bin/pip create mode 100755 env/bin/pip3 create mode 100755 env/bin/pip3.10 create mode 120000 env/bin/python create mode 120000 env/bin/python3 create mode 120000 env/bin/python3.10 create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt create mode 100644 env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt create mode 100644 env/lib/python3.10/site-packages/_distutils_hack/__init__.py create mode 100644 env/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/_distutils_hack/override.py create mode 100644 env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/blinker/__init__.py create mode 100644 env/lib/python3.10/site-packages/blinker/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/blinker/__pycache__/_saferef.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/blinker/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/blinker/_saferef.py create mode 100644 env/lib/python3.10/site-packages/blinker/_utilities.py create mode 100644 env/lib/python3.10/site-packages/blinker/base.py create mode 100644 env/lib/python3.10/site-packages/blinker/py.typed create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 env/lib/python3.10/site-packages/click/__init__.py create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/_compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/click/_compat.py create mode 100644 env/lib/python3.10/site-packages/click/_termui_impl.py create mode 100644 env/lib/python3.10/site-packages/click/_textwrap.py create mode 100644 env/lib/python3.10/site-packages/click/_winconsole.py create mode 100644 env/lib/python3.10/site-packages/click/core.py create mode 100644 env/lib/python3.10/site-packages/click/decorators.py create mode 100644 env/lib/python3.10/site-packages/click/exceptions.py create mode 100644 env/lib/python3.10/site-packages/click/formatting.py create mode 100644 env/lib/python3.10/site-packages/click/globals.py create mode 100644 env/lib/python3.10/site-packages/click/parser.py create mode 100644 env/lib/python3.10/site-packages/click/py.typed create mode 100644 env/lib/python3.10/site-packages/click/shell_completion.py create mode 100644 env/lib/python3.10/site-packages/click/termui.py create mode 100644 env/lib/python3.10/site-packages/click/testing.py create mode 100644 env/lib/python3.10/site-packages/click/types.py create mode 100644 env/lib/python3.10/site-packages/click/utils.py create mode 100644 env/lib/python3.10/site-packages/distutils-precedence.pth create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/flask-3.0.0.dist-info/entry_points.txt create mode 100644 env/lib/python3.10/site-packages/flask/__init__.py create mode 100644 env/lib/python3.10/site-packages/flask/__main__.py create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/__main__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/cli.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/ctx.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/typing.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/app.py create mode 100644 env/lib/python3.10/site-packages/flask/blueprints.py create mode 100644 env/lib/python3.10/site-packages/flask/cli.py create mode 100644 env/lib/python3.10/site-packages/flask/config.py create mode 100644 env/lib/python3.10/site-packages/flask/ctx.py create mode 100644 env/lib/python3.10/site-packages/flask/debughelpers.py create mode 100644 env/lib/python3.10/site-packages/flask/globals.py create mode 100644 env/lib/python3.10/site-packages/flask/helpers.py create mode 100644 env/lib/python3.10/site-packages/flask/json/__init__.py create mode 100644 env/lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/json/__pycache__/provider.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/json/__pycache__/tag.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/json/provider.py create mode 100644 env/lib/python3.10/site-packages/flask/json/tag.py create mode 100644 env/lib/python3.10/site-packages/flask/logging.py create mode 100644 env/lib/python3.10/site-packages/flask/py.typed create mode 100644 env/lib/python3.10/site-packages/flask/sansio/README.md create mode 100644 env/lib/python3.10/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/flask/sansio/app.py create mode 100644 env/lib/python3.10/site-packages/flask/sansio/blueprints.py create mode 100644 env/lib/python3.10/site-packages/flask/sansio/scaffold.py create mode 100644 env/lib/python3.10/site-packages/flask/sessions.py create mode 100644 env/lib/python3.10/site-packages/flask/signals.py create mode 100644 env/lib/python3.10/site-packages/flask/templating.py create mode 100644 env/lib/python3.10/site-packages/flask/testing.py create mode 100644 env/lib/python3.10/site-packages/flask/typing.py create mode 100644 env/lib/python3.10/site-packages/flask/views.py create mode 100644 env/lib/python3.10/site-packages/flask/wrappers.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__init__.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/_json.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/signer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/itsdangerous/_json.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/encoding.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/exc.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/py.typed create mode 100644 env/lib/python3.10/site-packages/itsdangerous/serializer.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/signer.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/timed.py create mode 100644 env/lib/python3.10/site-packages/itsdangerous/url_safe.py create mode 100644 env/lib/python3.10/site-packages/jinja2/__init__.py create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/_identifier.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/constants.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/debug.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/environment.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/ext.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/filters.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/meta.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/nodes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/parser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/sandbox.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/tests.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/jinja2/_identifier.py create mode 100644 env/lib/python3.10/site-packages/jinja2/async_utils.py create mode 100644 env/lib/python3.10/site-packages/jinja2/bccache.py create mode 100644 env/lib/python3.10/site-packages/jinja2/compiler.py create mode 100644 env/lib/python3.10/site-packages/jinja2/constants.py create mode 100644 env/lib/python3.10/site-packages/jinja2/debug.py create mode 100644 env/lib/python3.10/site-packages/jinja2/defaults.py create mode 100644 env/lib/python3.10/site-packages/jinja2/environment.py create mode 100644 env/lib/python3.10/site-packages/jinja2/exceptions.py create mode 100644 env/lib/python3.10/site-packages/jinja2/ext.py create mode 100644 env/lib/python3.10/site-packages/jinja2/filters.py create mode 100644 env/lib/python3.10/site-packages/jinja2/idtracking.py create mode 100644 env/lib/python3.10/site-packages/jinja2/lexer.py create mode 100644 env/lib/python3.10/site-packages/jinja2/loaders.py create mode 100644 env/lib/python3.10/site-packages/jinja2/meta.py create mode 100644 env/lib/python3.10/site-packages/jinja2/nativetypes.py create mode 100644 env/lib/python3.10/site-packages/jinja2/nodes.py create mode 100644 env/lib/python3.10/site-packages/jinja2/optimizer.py create mode 100644 env/lib/python3.10/site-packages/jinja2/parser.py create mode 100644 env/lib/python3.10/site-packages/jinja2/py.typed create mode 100644 env/lib/python3.10/site-packages/jinja2/runtime.py create mode 100644 env/lib/python3.10/site-packages/jinja2/sandbox.py create mode 100644 env/lib/python3.10/site-packages/jinja2/tests.py create mode 100644 env/lib/python3.10/site-packages/jinja2/utils.py create mode 100644 env/lib/python3.10/site-packages/jinja2/visitor.py create mode 100644 env/lib/python3.10/site-packages/markupsafe/__init__.py create mode 100644 env/lib/python3.10/site-packages/markupsafe/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/markupsafe/__pycache__/_native.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/markupsafe/_native.py create mode 100644 env/lib/python3.10/site-packages/markupsafe/_speedups.c create mode 100755 env/lib/python3.10/site-packages/markupsafe/_speedups.cpython-310-x86_64-linux-gnu.so create mode 100644 env/lib/python3.10/site-packages/markupsafe/_speedups.pyi create mode 100644 env/lib/python3.10/site-packages/markupsafe/py.typed create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/LICENSE.txt create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/entry_points.txt create mode 100644 env/lib/python3.10/site-packages/pip-22.0.2.dist-info/top_level.txt create mode 100644 env/lib/python3.10/site-packages/pip/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/__main__.py create mode 100644 env/lib/python3.10/site-packages/pip/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/__pycache__/__main__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/build_env.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/base_command.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/command_context.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/main.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/main_parser.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/parser.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/req_command.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/spinners.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/cli/status_codes.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/check.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/completion.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/configuration.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/debug.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/download.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/freeze.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/hash.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/help.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/index.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/install.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/list.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/search.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/show.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/uninstall.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/commands/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/configuration.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/installed.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/sdist.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/distributions/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/exceptions.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/__pycache__/collector.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/__pycache__/sources.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/collector.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/package_finder.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/index/sources.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/_distutils.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/locations/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/main.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/metadata/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/metadata/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/candidate.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/direct_url.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/format_control.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/index.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/link.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/scheme.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/search_scope.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/target_python.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/auth.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/download.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/session.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/auth.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/download.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/session.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/utils.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/check.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/check.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/freeze.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/operations/prepare.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/pyproject.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/constructors.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_file.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_install.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_set.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/constructors.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/req_file.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/req_install.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/req_set.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/req_tracker.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/self_outdated_check.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/_log.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/logging.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/misc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/models.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/urls.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/_log.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/appdirs.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/datetime.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/deprecation.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/egg_link.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/encoding.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/filesystem.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/filetypes.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/glibc.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/hashes.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/logging.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/misc.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/models.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/packaging.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/subprocess.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/unpacking.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/urls.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/utils/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/git.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/git.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/subversion.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/wheel_builder.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/__pycache__/distro.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/__pycache__/six.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/certifi/core.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/enums.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/chardet/version.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/win32.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/database.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/index.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/locators.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/markers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/resources.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/util.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/version.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/distro.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/core.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/codec.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/core.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/intranges.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/package_data.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/markers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/tags.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/utils.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/packaging/version.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/build.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/check.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/dirtools.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/meta.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/colors.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/bar.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/colors.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/counter.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/progress/spinner.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/console.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/filter.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/style.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/token.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pygments/util.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/api.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/help.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/models.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/__version__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/adapters.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/api.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/auth.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/certs.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/compat.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/cookies.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/help.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/hooks.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/models.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/packages.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/sessions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/structures.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/requests/utils.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__main__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_lru_cache.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/align.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/box.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/color.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/console.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/control.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/json.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/live.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/region.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/status.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/style.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/table.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/tabulate.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/text.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_extension.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_loop.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_lru_cache.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_pick.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_stack.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_timer.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_windows.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/abc.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/align.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/ansi.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/bar.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/box.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/cells.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/color.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/columns.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/console.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/constrain.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/containers.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/control.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/emoji.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/errors.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/filesize.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/json.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/layout.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/live.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/live_render.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/logging.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/markup.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/measure.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/padding.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/pager.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/palette.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/panel.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/pretty.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/progress.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/prompt.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/protocol.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/region.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/repr.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/rule.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/scope.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/screen.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/segment.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/spinner.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/status.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/style.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/styled.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/syntax.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/table.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/tabulate.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/text.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/theme.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/themes.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/traceback.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/rich/tree.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/six.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/after.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/before.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/tomli/_re.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/typing_extensions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/request.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/response.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/vendor.txt create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 env/lib/python3.10/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 env/lib/python3.10/site-packages/pip/py.typed create mode 100644 env/lib/python3.10/site-packages/pkg_resources/__init__.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_manylinux.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_musllinux.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/extern/__init__.py create mode 100644 env/lib/python3.10/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/LICENSE create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/entry_points.txt create mode 100644 env/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/top_level.txt create mode 100644 env/lib/python3.10/site-packages/setuptools/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/_imp.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/archive_util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/build_meta.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/config.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/dep_util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/depends.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/dist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/errors.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/extension.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/glob.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/installer.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/launch.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/monkey.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/msvc.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/namespaces.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/package_index.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/py34compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/sandbox.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/__pycache__/windows_support.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_deprecation_warning.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/config.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/core.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/debug.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/errors.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/extension.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/log.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/py35compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/util.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/archive_util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/cmd.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_msi.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_wininst.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/build.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/check.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/clean.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/config.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/install.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/register.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/command/upload.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/config.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/core.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/debug.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/dep_util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/dir_util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/dist.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/errors.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/extension.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/file_util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/filelist.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/log.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/py35compat.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/py38compat.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/spawn.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/text_file.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/version.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_imp.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/more.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/recipes.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/_manylinux.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/_musllinux.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 env/lib/python3.10/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 env/lib/python3.10/site-packages/setuptools/archive_util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/build_meta.py create mode 100644 env/lib/python3.10/site-packages/setuptools/cli-32.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/cli-64.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/cli-arm64.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/cli.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/alias.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/build_py.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/develop.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/dist_info.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/easy_install.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/egg_info.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/install.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/py36compat.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/register.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/rotate.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/saveopts.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/sdist.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/setopt.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/test.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/upload.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/__pycache__/upload_docs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/command/alias.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/bdist_egg.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/bdist_rpm.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/build_clib.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/build_ext.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/build_py.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/develop.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/dist_info.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/easy_install.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/egg_info.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/install.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/install_egg_info.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/install_lib.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/install_scripts.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/launcher manifest.xml create mode 100644 env/lib/python3.10/site-packages/setuptools/command/py36compat.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/register.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/rotate.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/saveopts.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/sdist.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/setopt.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/test.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/upload.py create mode 100644 env/lib/python3.10/site-packages/setuptools/command/upload_docs.py create mode 100644 env/lib/python3.10/site-packages/setuptools/config.py create mode 100644 env/lib/python3.10/site-packages/setuptools/dep_util.py create mode 100644 env/lib/python3.10/site-packages/setuptools/depends.py create mode 100644 env/lib/python3.10/site-packages/setuptools/dist.py create mode 100644 env/lib/python3.10/site-packages/setuptools/errors.py create mode 100644 env/lib/python3.10/site-packages/setuptools/extension.py create mode 100644 env/lib/python3.10/site-packages/setuptools/extern/__init__.py create mode 100644 env/lib/python3.10/site-packages/setuptools/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/setuptools/glob.py create mode 100644 env/lib/python3.10/site-packages/setuptools/gui-32.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/gui-64.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/gui-arm64.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/gui.exe create mode 100644 env/lib/python3.10/site-packages/setuptools/installer.py create mode 100644 env/lib/python3.10/site-packages/setuptools/launch.py create mode 100644 env/lib/python3.10/site-packages/setuptools/monkey.py create mode 100644 env/lib/python3.10/site-packages/setuptools/msvc.py create mode 100644 env/lib/python3.10/site-packages/setuptools/namespaces.py create mode 100644 env/lib/python3.10/site-packages/setuptools/package_index.py create mode 100644 env/lib/python3.10/site-packages/setuptools/py34compat.py create mode 100644 env/lib/python3.10/site-packages/setuptools/sandbox.py create mode 100644 env/lib/python3.10/site-packages/setuptools/script (dev).tmpl create mode 100644 env/lib/python3.10/site-packages/setuptools/script.tmpl create mode 100644 env/lib/python3.10/site-packages/setuptools/unicode_utils.py create mode 100644 env/lib/python3.10/site-packages/setuptools/version.py create mode 100644 env/lib/python3.10/site-packages/setuptools/wheel.py create mode 100644 env/lib/python3.10/site-packages/setuptools/windows_support.py create mode 100644 env/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/INSTALLER create mode 100644 env/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/LICENSE.rst create mode 100644 env/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/METADATA create mode 100644 env/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/RECORD create mode 100644 env/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/REQUESTED create mode 100644 env/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/WHEEL create mode 100644 env/lib/python3.10/site-packages/werkzeug/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/_internal.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/_reloader.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/formparser.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/http.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/local.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/security.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/serving.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/test.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/testapp.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/urls.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/user_agent.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/__pycache__/wsgi.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/_internal.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/_reloader.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/range.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/accept.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/accept.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/auth.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/cache_control.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/csp.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/csp.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/etag.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/etag.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/file_storage.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/headers.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/headers.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/mixins.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/mixins.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/range.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/range.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/structures.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/datastructures/structures.pyi create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/__pycache__/console.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/__pycache__/repr.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/console.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/repr.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/shared/console.png create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/shared/less.png create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/shared/more.png create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/shared/style.css create mode 100644 env/lib/python3.10/site-packages/werkzeug/debug/tbtools.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/exceptions.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/formparser.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/http.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/local.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/lint.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/lint.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/profiler.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/middleware/shared_data.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/py.typed create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__pycache__/converters.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__pycache__/map.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__pycache__/matcher.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/__pycache__/rules.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/converters.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/exceptions.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/map.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/matcher.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/routing/rules.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/http.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/request.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/response.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/utils.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/http.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/multipart.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/request.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/response.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/sansio/utils.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/security.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/serving.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/test.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/testapp.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/urls.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/user_agent.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/utils.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/wrappers/__init__.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/request.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/response.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/werkzeug/wrappers/request.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/wrappers/response.py create mode 100644 env/lib/python3.10/site-packages/werkzeug/wsgi.py create mode 120000 env/lib64 create mode 100644 env/pyvenv.cfg create mode 100644 templates/second_page.html diff --git a/__pycache__/app.cpython-310.pyc b/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9e5e6bdfdf0481284c74dafb86d82e650f755e6 GIT binary patch literal 506 zcmZ{hu};G<5Qc51ZrqkaUn5H`c7%{BF;+-LAa#k{_-KK+j+_)h*Rt^vF!q%^urM*h z)QNL4&;d^Jf4R%~?z_bH`(1+e{qO?s=s!ZRZxIG(c*-D}Xqpp4r_``1qXZ~K8#--4 z>y>NvMs=iH&jd5=I>Ry3)^VMQwV05k^NC$Z!aP6EReA4^94s}sv;tG)s)8MrS*X}I zhQSEWmq4kIU_-GJ8?QSvRl;ylnS4uK;M@`yqpM|iEEm>*oGG`)3G%|(JIJb1UQI^w z8fKGh0R}GZe4c|;MKLU%JikSlM;>N{p@O*%x^*l|$m~-8OXk9rKs0Cy(?ZP~FxSR6 zzfjFn*u(esO2ZTveuL|wj1%GcP53-6P}G}wk)}&!AWeOQu%0`+s-VWJ@BBGJoEWQD UIh;~#Qy!oUa3{gKR78jL2lgFnjsO4v literal 0 HcmV?d00001 diff --git a/app.py b/app.py index 15ebfe8..4243792 100644 --- a/app.py +++ b/app.py @@ -4,4 +4,8 @@ app = Flask(__name__) @app.route('/') def index(): - return render_template('base.html') \ No newline at end of file + return render_template('base.html') + +@app.route('/second') +def second_page(): + return render_template('second_page.html') \ No newline at end of file diff --git a/env/bin/Activate.ps1 b/env/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/env/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/env/bin/activate b/env/bin/activate new file mode 100644 index 0000000..37db385 --- /dev/null +++ b/env/bin/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/home/barzder/Projects/VSC/WebSchemeToggle/env" +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="(env) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(env) " + 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/env/bin/activate.csh b/env/bin/activate.csh new file mode 100644 index 0000000..865fc87 --- /dev/null +++ b/env/bin/activate.csh @@ -0,0 +1,26 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/barzder/Projects/VSC/WebSchemeToggle/env" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(env) $prompt" + setenv VIRTUAL_ENV_PROMPT "(env) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/env/bin/activate.fish b/env/bin/activate.fish new file mode 100644 index 0000000..fe3ec21 --- /dev/null +++ b/env/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/barzder/Projects/VSC/WebSchemeToggle/env" + +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) "(env) " (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 "(env) " +end diff --git a/env/bin/flask b/env/bin/flask new file mode 100755 index 0000000..b9bb766 --- /dev/null +++ b/env/bin/flask @@ -0,0 +1,8 @@ +#!/home/barzder/Projects/VSC/WebSchemeToggle/env/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/env/bin/pip b/env/bin/pip new file mode 100755 index 0000000..41379d7 --- /dev/null +++ b/env/bin/pip @@ -0,0 +1,8 @@ +#!/home/barzder/Projects/VSC/WebSchemeToggle/env/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/env/bin/pip3 b/env/bin/pip3 new file mode 100755 index 0000000..41379d7 --- /dev/null +++ b/env/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/barzder/Projects/VSC/WebSchemeToggle/env/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/env/bin/pip3.10 b/env/bin/pip3.10 new file mode 100755 index 0000000..41379d7 --- /dev/null +++ b/env/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/home/barzder/Projects/VSC/WebSchemeToggle/env/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/env/bin/python b/env/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/env/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/env/bin/python3 b/env/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/env/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/env/bin/python3.10 b/env/bin/python3.10 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/env/bin/python3.10 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA new file mode 100644 index 0000000..f54bb5c --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD new file mode 100644 index 0000000..c65e7ba --- /dev/null +++ b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD @@ -0,0 +1,59 @@ +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/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +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/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/REQUESTED b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt new file mode 100644 index 0000000..7b9666c --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/env/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.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/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/METADATA b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/METADATA new file mode 100644 index 0000000..bced165 --- /dev/null +++ b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/METADATA @@ -0,0 +1,93 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.3 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +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: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +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/ +- Chat: https://discord.gg/pallets diff --git a/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/RECORD b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/RECORD new file mode 100644 index 0000000..7686087 --- /dev/null +++ b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/RECORD @@ -0,0 +1,15 @@ +MarkupSafe-2.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.3.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.1.3.dist-info/METADATA,sha256=Wvvh4Tz-YtW24YagYdqrrrBdm9m-DjTdqJWhxlbU6-0,3003 +MarkupSafe-2.1.3.dist-info/RECORD,, +MarkupSafe-2.1.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +MarkupSafe-2.1.3.dist-info/WHEEL,sha256=iZaXX0Td62Nww8bojl0E84uJHjT41csHPKZmbUBbJPs,152 +MarkupSafe-2.1.3.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=xIItqrn1Bwi7FxPJO9rCVQBG0Evewue1Tl4BV0l9xEs,10338 +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-x86_64-linux-gnu.so,sha256=huh9xBZy3L1q1ar3y-f44Ozfa25Rg6xiomsq8MThk_Y,44240 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/REQUESTED b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL new file mode 100644 index 0000000..2d1b4b8 --- /dev/null +++ b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: false +Tag: cp310-cp310-manylinux_2_17_x86_64 +Tag: cp310-cp310-manylinux2014_x86_64 + diff --git a/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/env/lib/python3.10/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/env/lib/python3.10/site-packages/_distutils_hack/__init__.py b/env/lib/python3.10/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..f707416 --- /dev/null +++ b/env/lib/python3.10/site-packages/_distutils_hack/__init__.py @@ -0,0 +1,132 @@ +import sys +import os +import re +import importlib +import warnings + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +warnings.filterwarnings('ignore', + r'.+ distutils\b.+ deprecated', + DeprecationWarning) + + +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 + 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 + warnings.warn("Setuptools is replacing distutils.") + mods = [name for name in sys.modules if re.match(r'distutils\b', name)] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib') + return which == 'local' + + +def ensure_local_distutils(): + clear_distutils() + + # With the DistutilsMetaFinder in place, + # perform an import to cause distutils to be + # loaded from setuptools._distutils. Ref #2906. + add_shim() + importlib.import_module('distutils') + remove_shim() + + # check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + + +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 DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + if path is not None: + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + import importlib.abc + import importlib.util + + class DistutilsLoader(importlib.abc.Loader): + + def create_module(self, spec): + return importlib.import_module('setuptools._distutils') + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader('distutils', DistutilsLoader()) + + 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 + + @staticmethod + def pip_imported_during_build(): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + return any( + frame.f_globals['__file__'].endswith('setup.py') + for frame, line in traceback.walk_stack(None) + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass diff --git a/env/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ec58f0c8229cf17b7d20b4f8159c68763caf413 GIT binary patch literal 5122 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 uet=YkP#kSS`FJoIf>9Rxg)_{zsMo literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/_distutils_hack/override.py b/env/lib/python3.10/site-packages/_distutils_hack/override.py new file mode 100644 index 0000000..2cc433a --- /dev/null +++ b/env/lib/python3.10/site-packages/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst new file mode 100644 index 0000000..79c9825 --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst @@ -0,0 +1,20 @@ +Copyright 2010 Jason Kirtland + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA new file mode 100644 index 0000000..f96613c --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA @@ -0,0 +1,62 @@ +Metadata-Version: 2.1 +Name: blinker +Version: 1.7.0 +Summary: Fast, simple object-to-object and broadcast signaling +Keywords: signal,emit,events,broadcast +Author-email: Jason Kirtland +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Homepage, https://blinker.readthedocs.io +Project-URL: Issue Tracker, https://github.com/pallets-eco/blinker/issues/ +Project-URL: Source Code, https://github.com/pallets-eco/blinker/ + +Blinker +======= + +Blinker provides a fast dispatching system that allows any number of +interested parties to subscribe to events, or "signals". + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +.. code-block:: pycon + + >>> from blinker import signal + >>> started = signal('round-started') + >>> def each(round): + ... print(f"Round {round}") + ... + >>> started.connect(each) + + >>> def round_two(round): + ... print("This is round two.") + ... + >>> started.connect(round_two, sender=2) + + >>> for round in range(1, 4): + ... started.send(round) + ... + Round 1! + Round 2! + This is round two. + Round 3! + + +Links +----- + +- Documentation: https://blinker.readthedocs.io/ +- Changes: https://blinker.readthedocs.io/#changes +- PyPI Releases: https://pypi.org/project/blinker/ +- Source Code: https://github.com/pallets-eco/blinker/ +- Issue Tracker: https://github.com/pallets-eco/blinker/issues/ + diff --git a/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD new file mode 100644 index 0000000..f9c4581 --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD @@ -0,0 +1,15 @@ +blinker-1.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.7.0.dist-info/LICENSE.rst,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.7.0.dist-info/METADATA,sha256=kDgzPgrw4he78pEX88bSAqwYMVWrfUMk8QmNjekjg_U,1918 +blinker-1.7.0.dist-info/RECORD,, +blinker-1.7.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +blinker-1.7.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +blinker/__init__.py,sha256=s75XaRDHwSDzZ21BZUOEkQDQIcQEyT8hT7vk3EhYFQU,408 +blinker/__pycache__/__init__.cpython-310.pyc,, +blinker/__pycache__/_saferef.cpython-310.pyc,, +blinker/__pycache__/_utilities.cpython-310.pyc,, +blinker/__pycache__/base.cpython-310.pyc,, +blinker/_saferef.py,sha256=kWOTIWnCY3kOb8lZP74Rbx7bR_BLVg4TjwzNCRLhKHs,9096 +blinker/_utilities.py,sha256=S2njKDmlBpK_yCK4RT8hq98hEj30I0TQCC5mNhtY22I,2856 +blinker/base.py,sha256=FqZmAI5YzuRrvRmye1Jb-utyVOjXtF5vUVP3-1u-HtU,20544 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/REQUESTED b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/env/lib/python3.10/site-packages/blinker/__init__.py b/env/lib/python3.10/site-packages/blinker/__init__.py new file mode 100644 index 0000000..d014caa --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker/__init__.py @@ -0,0 +1,19 @@ +from blinker.base import ANY +from blinker.base import NamedSignal +from blinker.base import Namespace +from blinker.base import receiver_connected +from blinker.base import Signal +from blinker.base import signal +from blinker.base import WeakNamespace + +__all__ = [ + "ANY", + "NamedSignal", + "Namespace", + "Signal", + "WeakNamespace", + "receiver_connected", + "signal", +] + +__version__ = "1.7.0" diff --git a/env/lib/python3.10/site-packages/blinker/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/blinker/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6af77706f44cfdae4d92b9430af9954a319358a GIT binary patch literal 511 zcmZ9Jy-ve06ou{lH%%Abq62ZO4lD?P*ej$UD!f=pe3gdgr?Nw(_7!*mW;R|a8)D)W zn7EFBB5e8iJJCJKjonTrA;Iysc!Fn2$h$FrhlS=6mzF4!NLrDaa!L(b$QHK-wvlaa z59}a2+!@$KcDXyShwO20U?17%J|zW_!3*Vq9PyD16EYot;Frjh_V(5C9=Gu_twAPb z(WDjHk+FK4=78ozK@Q~(l*rqrfxH8WPrct_PyfUwD@ZrTsISbADcgu+#4{2YagF#W z2X`Ky#k1u!?4ztIn+>QqOEvtD4uK(WQo~DnUx>7-gy_dYV0*f38zEkaicE!(Pr=r0 z4J=F5L4sm8s(rxzHM>i$*$T2GUqcPIZBbOfpxLpi%-D9{t=nc1&u2`R9h~ARY|;WW k`)-d3Q8r~KM7-Vi!Fk=v#|kd+T8TbEiAY3`Gq8g23-U>OL;wH) literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/blinker/__pycache__/_saferef.cpython-310.pyc b/env/lib/python3.10/site-packages/blinker/__pycache__/_saferef.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac5281b19f77bf3f73eb5e63045c203c31502233 GIT binary patch literal 7198 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc b/env/lib/python3.10/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..677dac5ef31ee0936eb8798113504fba6936e8cc GIT binary patch literal 3537 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 lo0ixq`xKns1=yhlXFQ+#F@NpvAYAfrV*kYW#6 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 +# OWNER 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. +# +"""Refactored 'safe reference from dispatcher.py""" +import operator +import sys +import traceback +import weakref + + +get_self = operator.attrgetter("__self__") +get_func = operator.attrgetter("__func__") + + +def safe_ref(target, on_delete=None): + """Return a *safe* weak reference to a callable target. + + - ``target``: The object to be weakly referenced, if it's a bound + method reference, will create a BoundMethodWeakref, otherwise + creates a simple weakref. + + - ``on_delete``: If provided, will have a hard reference stored to + the callable to be called after the safe reference goes out of + scope with the reference object, (either a weakref or a + BoundMethodWeakref) as argument. + """ + try: + im_self = get_self(target) + except AttributeError: + if callable(on_delete): + return weakref.ref(target, on_delete) + else: + return weakref.ref(target) + else: + if im_self is not None: + # Turn a bound method into a BoundMethodWeakref instance. + # Keep track of these instances for lookup by disconnect(). + assert hasattr(target, "im_func") or hasattr(target, "__func__"), ( + f"safe_ref target {target!r} has im_self, but no im_func, " + "don't know how to create reference" + ) + reference = BoundMethodWeakref(target=target, on_delete=on_delete) + return reference + + +class BoundMethodWeakref: + """'Safe' and reusable weak references to instance methods. + + BoundMethodWeakref objects provide a mechanism for referencing a + bound method without requiring that the method object itself + (which is normally a transient object) is kept alive. Instead, + the BoundMethodWeakref object keeps weak references to both the + object and the function which together define the instance method. + + Attributes: + + - ``key``: The identity key for the reference, calculated by the + class's calculate_key method applied to the target instance method. + + - ``deletion_methods``: Sequence of callable objects taking single + argument, a reference to this object which will be called when + *either* the target object or target function is garbage + collected (i.e. when this object becomes invalid). These are + specified as the on_delete parameters of safe_ref calls. + + - ``weak_self``: Weak reference to the target object. + + - ``weak_func``: Weak reference to the target function. + + Class Attributes: + + - ``_all_instances``: Class attribute pointing to all live + BoundMethodWeakref objects indexed by the class's + calculate_key(target) method applied to the target objects. + This weak value dictionary is used to short-circuit creation so + that multiple references to the same (object, function) pair + produce the same BoundMethodWeakref instance. + """ + + _all_instances = weakref.WeakValueDictionary() # type: ignore[var-annotated] + + def __new__(cls, target, on_delete=None, *arguments, **named): + """Create new instance or return current instance. + + Basically this method of construction allows us to + short-circuit creation of references to already-referenced + instance methods. The key corresponding to the target is + calculated, and if there is already an existing reference, + that is returned, with its deletion_methods attribute updated. + Otherwise the new instance is created and registered in the + table of already-referenced methods. + """ + key = cls.calculate_key(target) + current = cls._all_instances.get(key) + if current is not None: + current.deletion_methods.append(on_delete) + return current + else: + base = super().__new__(cls) + cls._all_instances[key] = base + base.__init__(target, on_delete, *arguments, **named) + return base + + def __init__(self, target, on_delete=None): + """Return a weak-reference-like instance for a bound method. + + - ``target``: The instance-method target for the weak reference, + must have im_self and im_func attributes and be + reconstructable via the following, which is true of built-in + instance methods:: + + target.im_func.__get__( target.im_self ) + + - ``on_delete``: Optional callback which will be called when + this weak reference ceases to be valid (i.e. either the + object or the function is garbage collected). Should take a + single argument, which will be passed a pointer to this + object. + """ + + def remove(weak, self=self): + """Set self.isDead to True when method or instance is destroyed.""" + methods = self.deletion_methods[:] + del self.deletion_methods[:] + try: + del self.__class__._all_instances[self.key] + except KeyError: + pass + for function in methods: + try: + if callable(function): + function(self) + except Exception: + try: + traceback.print_exc() + except AttributeError: + e = sys.exc_info()[1] + print( + f"Exception during saferef {self} " + f"cleanup function {function}: {e}" + ) + + self.deletion_methods = [on_delete] + self.key = self.calculate_key(target) + im_self = get_self(target) + im_func = get_func(target) + self.weak_self = weakref.ref(im_self, remove) + self.weak_func = weakref.ref(im_func, remove) + self.self_name = str(im_self) + self.func_name = str(im_func.__name__) + + @classmethod + def calculate_key(cls, target): + """Calculate the reference key for this reference. + + Currently this is a two-tuple of the id()'s of the target + object and the target function respectively. + """ + return (id(get_self(target)), id(get_func(target))) + + def __str__(self): + """Give a friendly representation of the object.""" + return "{}({}.{})".format( + self.__class__.__name__, + self.self_name, + self.func_name, + ) + + __repr__ = __str__ + + def __hash__(self): + return hash((self.self_name, self.key)) + + def __nonzero__(self): + """Whether we are still a valid reference.""" + return self() is not None + + def __eq__(self, other): + """Compare with another reference.""" + if not isinstance(other, self.__class__): + return operator.eq(self.__class__, type(other)) + return operator.eq(self.key, other.key) + + def __call__(self): + """Return a strong reference to the bound method. + + If the target cannot be retrieved, then will return None, + otherwise returns a bound instance method for our object and + function. + + Note: You may call this method any number of times, as it does + not invalidate the reference. + """ + target = self.weak_self() + if target is not None: + function = self.weak_func() + if function is not None: + return function.__get__(target) + return None diff --git a/env/lib/python3.10/site-packages/blinker/_utilities.py b/env/lib/python3.10/site-packages/blinker/_utilities.py new file mode 100644 index 0000000..4b711c6 --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker/_utilities.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +import typing as t +from weakref import ref + +from blinker._saferef import BoundMethodWeakref + +IdentityType = t.Union[t.Tuple[int, int], str, int] + + +class _symbol: + def __init__(self, name): + """Construct a new named symbol.""" + self.__name__ = self.name = name + + def __reduce__(self): + return symbol, (self.name,) + + def __repr__(self): + return self.name + + +_symbol.__name__ = "symbol" + + +class symbol: + """A constant symbol. + + >>> symbol('foo') is symbol('foo') + True + >>> symbol('foo') + foo + + A slight refinement of the MAGICCOOKIE=object() pattern. The primary + advantage of symbol() is its repr(). They are also singletons. + + Repeated calls of symbol('name') will all return the same instance. + + """ + + symbols = {} # type: ignore[var-annotated] + + def __new__(cls, name): + try: + return cls.symbols[name] + except KeyError: + return cls.symbols.setdefault(name, _symbol(name)) + + +def hashable_identity(obj: object) -> IdentityType: + if hasattr(obj, "__func__"): + return (id(obj.__func__), id(obj.__self__)) # type: ignore[attr-defined] + elif hasattr(obj, "im_func"): + return (id(obj.im_func), id(obj.im_self)) # type: ignore[attr-defined] + elif isinstance(obj, (int, str)): + return obj + else: + return id(obj) + + +WeakTypes = (ref, BoundMethodWeakref) + + +class annotatable_weakref(ref): + """A weakref.ref that supports custom instance attributes.""" + + receiver_id: t.Optional[IdentityType] + sender_id: t.Optional[IdentityType] + + +def reference( # type: ignore[no-untyped-def] + object, callback=None, **annotations +) -> annotatable_weakref: + """Return an annotated weak ref.""" + if callable(object): + weak = callable_reference(object, callback) + else: + weak = annotatable_weakref(object, callback) + for key, value in annotations.items(): + setattr(weak, key, value) + return weak # type: ignore[no-any-return] + + +def callable_reference(object, callback=None): + """Return an annotated weak ref, supporting bound instance methods.""" + if hasattr(object, "im_self") and object.im_self is not None: + return BoundMethodWeakref(target=object, on_delete=callback) + elif hasattr(object, "__self__") and object.__self__ is not None: + return BoundMethodWeakref(target=object, on_delete=callback) + return annotatable_weakref(object, callback) + + +class lazy_property: + """A @property that is only evaluated once.""" + + def __init__(self, deferred): + self._deferred = deferred + self.__doc__ = deferred.__doc__ + + def __get__(self, obj, cls): + if obj is None: + return self + value = self._deferred(obj) + setattr(obj, self._deferred.__name__, value) + return value diff --git a/env/lib/python3.10/site-packages/blinker/base.py b/env/lib/python3.10/site-packages/blinker/base.py new file mode 100644 index 0000000..b9d7035 --- /dev/null +++ b/env/lib/python3.10/site-packages/blinker/base.py @@ -0,0 +1,558 @@ +"""Signals and events. + +A small implementation of signals, inspired by a snippet of Django signal +API client code seen in a blog post. Signals are first-class objects and +each manages its own receivers and message emission. + +The :func:`signal` function provides singleton behavior for named signals. + +""" +from __future__ import annotations + +import typing as t +from collections import defaultdict +from contextlib import contextmanager +from inspect import iscoroutinefunction +from warnings import warn +from weakref import WeakValueDictionary + +from blinker._utilities import annotatable_weakref +from blinker._utilities import hashable_identity +from blinker._utilities import IdentityType +from blinker._utilities import lazy_property +from blinker._utilities import reference +from blinker._utilities import symbol +from blinker._utilities import WeakTypes + +if t.TYPE_CHECKING: + import typing_extensions as te + + T_callable = t.TypeVar("T_callable", bound=t.Callable[..., t.Any]) + + T = t.TypeVar("T") + P = te.ParamSpec("P") + + AsyncWrapperType = t.Callable[[t.Callable[P, t.Awaitable[T]]], t.Callable[P, T]] + SyncWrapperType = t.Callable[[t.Callable[P, T]], t.Callable[P, t.Awaitable[T]]] + +ANY = symbol("ANY") +ANY.__doc__ = 'Token for "any sender".' +ANY_ID = 0 + +# NOTE: We need a reference to cast for use in weakref callbacks otherwise +# t.cast may have already been set to None during finalization. +cast = t.cast + + +class Signal: + """A notification emitter.""" + + #: An :obj:`ANY` convenience synonym, allows ``Signal.ANY`` + #: without an additional import. + ANY = ANY + + set_class: type[set] = set + + @lazy_property + def receiver_connected(self) -> Signal: + """Emitted after each :meth:`connect`. + + The signal sender is the signal instance, and the :meth:`connect` + arguments are passed through: *receiver*, *sender*, and *weak*. + + .. versionadded:: 1.2 + + """ + return Signal(doc="Emitted after a receiver connects.") + + @lazy_property + def receiver_disconnected(self) -> Signal: + """Emitted after :meth:`disconnect`. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: *receiver* and *sender*. + + Note, this signal is emitted **only** when :meth:`disconnect` is + called explicitly. + + The disconnect signal can not be emitted by an automatic disconnect + (due to a weakly referenced receiver or sender going out of scope), + as the receiver and/or sender instances are no longer available for + use at the time this signal would be emitted. + + An alternative approach is available by subscribing to + :attr:`receiver_connected` and setting up a custom weakref cleanup + callback on weak receivers and senders. + + .. versionadded:: 1.2 + + """ + return Signal(doc="Emitted after a receiver disconnects.") + + def __init__(self, doc: str | None = None) -> None: + """ + :param doc: optional. If provided, will be assigned to the signal's + __doc__ attribute. + + """ + if doc: + self.__doc__ = doc + #: A mapping of connected receivers. + #: + #: The values of this mapping are not meaningful outside of the + #: internal :class:`Signal` implementation, however the boolean value + #: of the mapping is useful as an extremely efficient check to see if + #: any receivers are connected to the signal. + self.receivers: dict[IdentityType, t.Callable | annotatable_weakref] = {} + self.is_muted = False + self._by_receiver: dict[IdentityType, set[IdentityType]] = defaultdict( + self.set_class + ) + self._by_sender: dict[IdentityType, set[IdentityType]] = defaultdict( + self.set_class + ) + self._weak_senders: dict[IdentityType, annotatable_weakref] = {} + + def connect( + self, receiver: T_callable, sender: t.Any = ANY, weak: bool = True + ) -> T_callable: + """Connect *receiver* to signal events sent by *sender*. + + :param receiver: A callable. Will be invoked by :meth:`send` with + `sender=` as a single positional argument and any ``kwargs`` that + were provided to a call to :meth:`send`. + + :param sender: Any object or :obj:`ANY`, defaults to ``ANY``. + Restricts notifications delivered to *receiver* to only those + :meth:`send` emissions sent by *sender*. If ``ANY``, the receiver + will always be notified. A *receiver* may be connected to + multiple *sender* values on the same Signal through multiple calls + to :meth:`connect`. + + :param weak: If true, the Signal will hold a weakref to *receiver* + and automatically disconnect when *receiver* goes out of scope or + is garbage collected. Defaults to True. + + """ + receiver_id = hashable_identity(receiver) + receiver_ref: T_callable | annotatable_weakref + + if weak: + receiver_ref = reference(receiver, self._cleanup_receiver) + receiver_ref.receiver_id = receiver_id + else: + receiver_ref = receiver + sender_id: IdentityType + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = hashable_identity(sender) + + self.receivers.setdefault(receiver_id, receiver_ref) + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + del receiver_ref + + if sender is not ANY and sender_id not in self._weak_senders: + # wire together a cleanup for weakref-able senders + try: + sender_ref = reference(sender, self._cleanup_sender) + sender_ref.sender_id = sender_id + except TypeError: + pass + else: + self._weak_senders.setdefault(sender_id, sender_ref) + del sender_ref + + # broadcast this connection. if receivers raise, disconnect. + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: + try: + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) + except TypeError as e: + self.disconnect(receiver, sender) + raise e + if receiver_connected.receivers and self is not receiver_connected: + try: + receiver_connected.send( + self, receiver_arg=receiver, sender_arg=sender, weak_arg=weak + ) + except TypeError as e: + self.disconnect(receiver, sender) + raise e + return receiver + + def connect_via( + self, sender: t.Any, weak: bool = False + ) -> t.Callable[[T_callable], T_callable]: + """Connect the decorated function as a receiver for *sender*. + + :param sender: Any object or :obj:`ANY`. The decorated function + will only receive :meth:`send` emissions sent by *sender*. If + ``ANY``, the receiver will always be notified. A function may be + decorated multiple times with differing *sender* values. + + :param weak: If true, the Signal will hold a weakref to the + decorated function and automatically disconnect when *receiver* + goes out of scope or is garbage collected. Unlike + :meth:`connect`, this defaults to False. + + The decorated function will be invoked by :meth:`send` with + `sender=` as a single positional argument and any ``kwargs`` that + were provided to the call to :meth:`send`. + + + .. versionadded:: 1.1 + + """ + + def decorator(fn: T_callable) -> T_callable: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: t.Callable, sender: t.Any = ANY + ) -> t.Generator[None, None, None]: + """Execute a block with the signal temporarily connected to *receiver*. + + :param receiver: a receiver callable + :param sender: optional, a sender to filter on + + This is a context manager for use in the ``with`` statement. It can + be useful in unit tests. *receiver* is connected to the signal for + the duration of the ``with`` block, and will be disconnected + automatically when exiting the block: + + .. code-block:: python + + with on_ready.connected_to(receiver): + # do stuff + on_ready.send(123) + + .. versionadded:: 1.1 + + """ + self.connect(receiver, sender=sender, weak=False) + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> t.Generator[None, None, None]: + """Context manager for temporarily disabling signal. + Useful for test purposes. + """ + self.is_muted = True + try: + yield None + except Exception as e: + raise e + finally: + self.is_muted = False + + def temporarily_connected_to( + self, receiver: t.Callable, sender: t.Any = ANY + ) -> t.ContextManager[None]: + """An alias for :meth:`connected_to`. + + :param receiver: a receiver callable + :param sender: optional, a sender to filter on + + .. versionadded:: 0.9 + + .. versionchanged:: 1.1 + Renamed to :meth:`connected_to`. ``temporarily_connected_to`` was + deprecated in 1.2 and will be removed in a subsequent version. + + """ + warn( + "temporarily_connected_to is deprecated; use connected_to instead.", + DeprecationWarning, + ) + return self.connected_to(receiver, sender) + + def send( + self, + *sender: t.Any, + _async_wrapper: AsyncWrapperType | None = None, + **kwargs: t.Any, + ) -> list[tuple[t.Callable, t.Any]]: + """Emit this signal on behalf of *sender*, passing on ``kwargs``. + + Returns a list of 2-tuples, pairing receivers with their return + value. The ordering of receiver notification is undefined. + + :param sender: Any object or ``None``. If omitted, synonymous + with ``None``. Only accepts one positional argument. + :param _async_wrapper: A callable that should wrap a coroutine + receiver and run it when called synchronously. + + :param kwargs: Data to be sent to receivers. + """ + if self.is_muted: + return [] + + sender = self._extract_sender(sender) + results = [] + for receiver in self.receivers_for(sender): + if iscoroutinefunction(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function") + receiver = _async_wrapper(receiver) + result = receiver(sender, **kwargs) + results.append((receiver, result)) + return results + + async def send_async( + self, + *sender: t.Any, + _sync_wrapper: SyncWrapperType | None = None, + **kwargs: t.Any, + ) -> list[tuple[t.Callable, t.Any]]: + """Emit this signal on behalf of *sender*, passing on ``kwargs``. + + Returns a list of 2-tuples, pairing receivers with their return + value. The ordering of receiver notification is undefined. + + :param sender: Any object or ``None``. If omitted, synonymous + with ``None``. Only accepts one positional argument. + :param _sync_wrapper: A callable that should wrap a synchronous + receiver and run it when awaited. + + :param kwargs: Data to be sent to receivers. + """ + if self.is_muted: + return [] + + sender = self._extract_sender(sender) + results = [] + for receiver in self.receivers_for(sender): + if not iscoroutinefunction(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function") + receiver = _sync_wrapper(receiver) + result = await receiver(sender, **kwargs) + results.append((receiver, result)) + return results + + def _extract_sender(self, sender: t.Any) -> t.Any: + if not self.receivers: + # Ensure correct signature even on no-op sends, disable with -O + # for lowest possible cost. + if __debug__ and sender and len(sender) > 1: + raise TypeError( + f"send() accepts only one positional argument, {len(sender)} given" + ) + return [] + + # Using '*sender' rather than 'sender=None' allows 'sender' to be + # used as a keyword argument- i.e. it's an invisible name in the + # function signature. + if len(sender) == 0: + sender = None + elif len(sender) > 1: + raise TypeError( + f"send() accepts only one positional argument, {len(sender)} given" + ) + else: + sender = sender[0] + return sender + + def has_receivers_for(self, sender: t.Any) -> bool: + """True if there is probably a receiver for *sender*. + + Performs an optimistic check only. Does not guarantee that all + weakly referenced receivers are still alive. See + :meth:`receivers_for` for a stronger search. + + """ + if not self.receivers: + return False + if self._by_sender[ANY_ID]: + return True + if sender is ANY: + return False + return hashable_identity(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> t.Generator[t.Callable[[t.Any], t.Any], None, None]: + """Iterate all live receivers listening for *sender*.""" + # TODO: test receivers_for(ANY) + if self.receivers: + sender_id = hashable_identity(sender) + if sender_id in self._by_sender: + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] + else: + ids = self._by_sender[ANY_ID].copy() + for receiver_id in ids: + receiver = self.receivers.get(receiver_id) + if receiver is None: + continue + if isinstance(receiver, WeakTypes): + strong = receiver() + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + receiver = strong + yield receiver # type: ignore[misc] + + def disconnect(self, receiver: t.Callable, sender: t.Any = ANY) -> None: + """Disconnect *receiver* from this signal's events. + + :param receiver: a previously :meth:`connected` callable + + :param sender: a specific sender to disconnect from, or :obj:`ANY` + to disconnect from all senders. Defaults to ``ANY``. + + """ + sender_id: IdentityType + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = hashable_identity(sender) + receiver_id = hashable_identity(receiver) + self._disconnect(receiver_id, sender_id) + + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) + + def _disconnect(self, receiver_id: IdentityType, sender_id: IdentityType) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, False): + for bucket in self._by_sender.values(): + bucket.discard(receiver_id) + self.receivers.pop(receiver_id, None) + else: + self._by_sender[sender_id].discard(receiver_id) + self._by_receiver[receiver_id].discard(sender_id) + + def _cleanup_receiver(self, receiver_ref: annotatable_weakref) -> None: + """Disconnect a receiver from all senders.""" + self._disconnect(cast(IdentityType, receiver_ref.receiver_id), ANY_ID) + + def _cleanup_sender(self, sender_ref: annotatable_weakref) -> None: + """Disconnect all receivers from a sender.""" + sender_id = cast(IdentityType, sender_ref.sender_id) + assert sender_id != ANY_ID + self._weak_senders.pop(sender_id, None) + for receiver_id in self._by_sender.pop(sender_id, ()): + self._by_receiver[receiver_id].discard(sender_id) + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leave behind a small amount of bookkeeping + for the receiver and sender values. Typical workloads using Blinker, + for example in most web apps, Flask, CLI scripts, etc., are not + adversely affected by this bookkeeping. + + With a long-running Python process performing dynamic signal routing + with high volume- e.g. connecting to function closures, "senders" are + all unique object instances, and doing all of this over and over- you + may see memory usage will grow due to extraneous bookkeeping. (An empty + set() for each stale sender/receiver pair.) + + This method will prune that bookkeeping away, with the caveat that such + pruning is not threadsafe. The risk is that cleanup of a fully + disconnected receiver/sender pair occurs while another thread is + connecting that same pair. If you are in the highly dynamic, unique + receiver/sender situation that has lead you to this method, that + failure mode is perhaps not a big deal for you. + """ + for mapping in (self._by_sender, self._by_receiver): + for _id, bucket in list(mapping.items()): + if not bucket: + mapping.pop(_id, None) + + def _clear_state(self) -> None: + """Throw away all signal state. Useful for unit tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +receiver_connected = Signal( + """\ +Sent by a :class:`Signal` after a receiver connects. + +:argument: the Signal that was connected to +:keyword receiver_arg: the connected receiver +:keyword sender_arg: the sender to connect to +:keyword weak_arg: true if the connection to receiver_arg is a weak reference + +.. deprecated:: 1.2 + +As of 1.2, individual signals have their own private +:attr:`~Signal.receiver_connected` and +:attr:`~Signal.receiver_disconnected` signals with a slightly simplified +call signature. This global signal is planned to be removed in 1.6. + +""" +) + + +class NamedSignal(Signal): + """A named generic notification emitter.""" + + def __init__(self, name: str, doc: str | None = None) -> None: + Signal.__init__(self, doc) + + #: The name of this signal. + self.name = name + + def __repr__(self) -> str: + base = Signal.__repr__(self) + return f"{base[:-1]}; {self.name!r}>" # noqa: E702 + + +class Namespace(dict): + """A mapping of signal names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` *name*, creating it if required. + + Repeated calls to this function will return the same signal object. + + """ + try: + return self[name] # type: ignore[no-any-return] + except KeyError: + result = self.setdefault(name, NamedSignal(name, doc)) + return result # type: ignore[no-any-return] + + +class WeakNamespace(WeakValueDictionary): + """A weak mapping of signal names to signals. + + Automatically cleans up unused Signals when the last reference goes out + of scope. This namespace implementation exists for a measure of legacy + compatibility with Blinker <= 1.2, and may be dropped in the future. + + .. versionadded:: 1.3 + + """ + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` *name*, creating it if required. + + Repeated calls to this function will return the same signal object. + + """ + try: + return self[name] # type: ignore[no-any-return] + except KeyError: + result = self.setdefault(name, NamedSignal(name, doc)) + return result # type: ignore[no-any-return] + + +signal = Namespace().signal diff --git a/env/lib/python3.10/site-packages/blinker/py.typed b/env/lib/python3.10/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Chat: https://discord.gg/pallets diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..1c017ef --- /dev/null +++ b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,40 @@ +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +click/__pycache__/__init__.cpython-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=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/REQUESTED b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/env/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/env/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/env/lib/python3.10/site-packages/click/__init__.py b/env/lib/python3.10/site-packages/click/__init__.py new file mode 100644 index 0000000..9a1dab0 --- /dev/null +++ b/env/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.7" diff --git a/env/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..580828c286365bff554cbfed9c0c530d435a4235 GIT binary patch literal 2630 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 EA1WlMQ2+n{ literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38a9c90338587ec3d8d5a830316e8d80d2a53749 GIT binary patch literal 16328 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 GvHuGk-|<@j literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e4df0e72580e498f93311ab220669a195adbc96 GIT binary patch literal 1564 zcmZWpOK;mo5Z+xbR}?MFjp6uFG`*z&4>i-~kV_B*NP!|nAry5G143JZ=B_156e;gg zeh3uM!tSX*At)dp`25DQxpO2uUQ(NO$o~y9{)eIV0ZXlzd5~Bl#7PT#2zI54@ltNKpg1=)V7l% zFV%TDiu1Uqbb|KPg>^iIZ6pXqx>OR#K$SD#%H4xZZ%>XAkVQyWieq0kq<6);4duzE za-|DiO)2)sF_*qvyW*F$>&sSspD{VKlI#t>z872Km zJ~Y-#COXQ}T-io_Qn_`{Qd#z`(5js1ypsTAZ&wpe2-h>%^&?7B@ygi+&@S1`t;m4t z`xTXJkIY0RB&pn=@!Y6H8p`? zQS^G53RQj@X6aElz9{=e{&4@Z2cbzz^(iD70t-x-WN9)CBP7Nd^kIK|Vedr!IF}g| z@uq&P%wXAjUE?!OmnMVd>MmkERTHw$0x!A26AZ$bP-pgm;9 zut_tgf<6vNMIRAHBDevKE;TxBN%E3VatKYS@D{uy;3_uhKmCjZv=cDfPV=-(<1AVf zVegp9kx?fTC}?R4xZZ#Q^bQESS!5FI?}Xe%+k0VkD;DA|Mz#Pz9WQ@#4=iRI1p84i zLEG?QfSX`G6}KLp?ye%X8fZB-;vJ}v8px5F)nCD(2QUG%>6~7ZOZo-*e&;(jb7mZ% zLzX*|4!Pb2%>j+gdF8%>Ie0~WWysqTPqI1Kukp{p>1gDxrG6l6Q{|J9(s8MfgjrhR zPmg>m^h#c?sEhI;Z+V*@m@ z&U(*Fd|09NM`*i`0_nUWu!-6Mfq0vbL3o5gb?hI{VSh8u{$eislL`Md+x(Djw`yNN y&BKP_UrASIuZiP5UcBfDcEaFLcmzjm+xZuxjfevP literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad8c25c4f4f362e0cad64fda724d083b6812fe31 GIT binary patch literal 7680 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ǧ=@|y%`n5fG|kOt*Cwx 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba2d673b218d9788dae0e8dd3d1cef1c7b269453 GIT binary patch literal 17228 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 GKl&e(nG~}C literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a0837c8f9ce986a556d03666bc77f03ba2404ab GIT binary patch literal 10272 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 Iojh&-FX$3FJpcdz literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ca7c2c8ab7da7aea277151ca134c9ff43af272b GIT binary patch literal 9477 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d947c49f824376198fd28ed1a15f94a778b2920 GIT binary patch literal 2449 zcmZ`*-EJF26y8~{9mh%BCT(fb78oS{j9R-;AtVbSP}D*MGF4+y)qw2r&e*%@cxN>; zwqq+rsO=r%9oozC1U$>$A+CDOU4>N6nYAIQ!b&@ynRE8ccmBSy+SsUg@ceP(7x8Sx z^Zvxe@dx(2&*3${!@xaGq}L(v>q~!B=oE-2$U&elI!Uop;sqYal~K7<21((O*I5O5 zg{2lQU6MzW$*A(PJuEMc{>s}d^??X9e2 zVkr{)V$+KHH?b9($?tD5X~d6NNeesHi4NeK5I6p={(cyVk!Y*oP>O~~CJh<)8|lnOD!Ebr z@Or}lq-!Y)@3WyWjZntn{l-wLJ|L{8v+UeZ*lsx18eHgxxle0|%7-EF^#=UZ{};P1 zBg|DC9ANzNKj?ZLmuTTEPO31Ru!Kk8XBY+3f?-~<-V?%!^$!Z%-|?RMcOfo;X9HUt z__KG3_ka*@UOn>6WeXMah#ZlJpmWdT!2|LW;lci5HYHQ9R%8$1h&wI^hT2Hbg`?Dk zfiB#wQ`(MVLqnF(zMx|xIAw-1I%P9zRfWRC!cdr3Y~;bBs*m}g1Fc4sC9`QHv{;%1 ztBj767Bn8E5c=5W)+Cfk!fZSdaDYSB9E_8&*-M!*%QW;T7opP3D!sIaN;Xyrjg2#u z>UhL-EN6&%FqU+nG>wEzg*McT!w4N&m=1K>L~Ig+%|64Zz`-Y?m`9*qac0_zrehPGrg4=vN5V$U-lA#hCRC~D9gq0J zNWD%cfE`?9oD1G;(vR!cbNkJdX*QyHw>4=zphj2>U$3plU<{Gv{YEEDjv?fR_F5_d z5$GmrnQjLbb9(H-JWW_ESzqS46A=3W8%qq*A_SlVhiMiYLD^|Wn&J>LcxRm0cqDFW zt#q&M^j!Zxe+ke0tu~eiLIXeyatRf1vKU*nm5kUd2$`{2sq085D;f(OoK?TDR>%FZ z&CO?(y@ZQHcT~21{NS4JSR^Cjv~IkB{k8>zf95>dA_1w8%FCco{@MRKD}?s&M3W*- zAw#()-G+(v4#*RqlOeR{lfserln@|wpvuDhgWFI50&6}I(`CGu6~62}=Sp3l15>S9 zpb&q^#!MZ#-DZ3EZC_u3pAg;?56YYi z$U?abPl19R$NTel?ue0^0CFrMt5Pb(L_jxTPvcgOxm7DTxDI<(NL6|aljA=mylf2w zOI#nphQn3$^&2QGhDs`ZBEkr*0I!4hK1_}P)|lwh5s;sS*z&@!kh)O0V#jbTQ@tcuCup@bUJp>3cq8aH^Ev*Un%)aQNlH!x zL=pnlT{!azs2hxOxd>(Jm;DlfONzoqjogB2a(8D5mKy(lxW=oIItW|^VI4a`3s9g! z%iUeI&8%c+DUhDViz-{Skrs^O8gr9vwC~-%+1>r>=I+;ftuM39T(=9izetd(Oy*kw z9Sc0~PF&P96qJ^Vap!Lq^p%oX`P&rvn@Lxtt|T1#Qwyp5=}7Uh6rW)a8Z7Iww@yla Vncx@{sw4=mkV`>jyHb3+_zyC8cpU%$ literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00230a9b793364aa5ab413c46c2d0ec53e462bb6 GIT binary patch literal 13690 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc b/env/lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e938259d54c752459ba0f644d446e3801dc2740 GIT binary patch literal 26150 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 p#Q*6=yXG~*XU6;5P0y^|`Esxv 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 q+ckD+?1iz3vDYW;v0b2aP!mV8FpN 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/click/_compat.py b/env/lib/python3.10/site-packages/click/_compat.py new file mode 100644 index 0000000..23f8866 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/_compat.py @@ -0,0 +1,623 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +WIN = sys.platform.startswith("win") +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO[t.Any]) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, "os.PathLike[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( # noqa: F811 + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/env/lib/python3.10/site-packages/click/_termui_impl.py b/env/lib/python3.10/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..f744657 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/_termui_impl.py @@ -0,0 +1,739 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ +from io import StringIO +from types import TracebackType + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/env/lib/python3.10/site-packages/click/_textwrap.py b/env/lib/python3.10/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/click/_winconsole.py b/env/lib/python3.10/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/click/core.py b/env/lib/python3.10/site-packages/click/core.py new file mode 100644 index 0000000..cc65e89 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/core.py @@ -0,0 +1,3042 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.MutableMapping[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invocable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": + ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: + ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt) as e: + echo(file=sys.stderr) + raise Abort() from e + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.MutableMapping[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The latter is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator[t.Any]: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return t.cast(Option, param).flag_value + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the constructor of :class:`Parameter`. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/env/lib/python3.10/site-packages/click/decorators.py b/env/lib/python3.10/site-packages/click/decorators.py new file mode 100644 index 0000000..d9bba95 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/decorators.py @@ -0,0 +1,561 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + return decorator # type: ignore[return-value] + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator # type: ignore[return-value] + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: + ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: + ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + message % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/env/lib/python3.10/site-packages/click/exceptions.py b/env/lib/python3.10/site-packages/click/exceptions.py new file mode 100644 index 0000000..fe68a36 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/exceptions.py @@ -0,0 +1,288 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd: t.Optional["Command"] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename: str = format_filename(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code: int = code diff --git a/env/lib/python3.10/site-packages/click/formatting.py b/env/lib/python3.10/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/click/globals.py b/env/lib/python3.10/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/env/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/env/lib/python3.10/site-packages/click/parser.py b/env/lib/python3.10/site-packages/click/parser.py new file mode 100644 index 0000000..5fa7adf --- /dev/null +++ b/env/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: t.Set[str] = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: t.Any, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List["CoreParameter"] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args: bool = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options: bool = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we recombine the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/env/lib/python3.10/site-packages/click/py.typed b/env/lib/python3.10/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/click/shell_completion.py b/env/lib/python3.10/site-packages/click/shell_completion.py new file mode 100644 index 0000000..dc9e00b --- /dev/null +++ b/env/lib/python3.10/site-packages/click/shell_completion.py @@ -0,0 +1,596 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + @staticmethod + def _check_version() -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + return cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + # Will be None if expose_value is False. + value = ctx.params.get(param.name) + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + sub_ctx = ctx + + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/env/lib/python3.10/site-packages/click/termui.py b/env/lib/python3.10/site-packages/click/termui.py new file mode 100644 index 0000000..db7a4b2 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/env/lib/python3.10/site-packages/click/testing.py b/env/lib/python3.10/site-packages/click/testing.py new file mode 100644 index 0000000..e0df0d2 --- /dev/null +++ b/env/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[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(input) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env: t.Mapping[str, t.Optional[str]] = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/env/lib/python3.10/site-packages/click/types.py b/env/lib/python3.10/site-packages/click/types.py new file mode 100644 index 0000000..2b1d179 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/types.py @@ -0,0 +1,1089 @@ +import os +import stat +import sys +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import format_filename +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name: str = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = sys.getfilesystemencoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type[t.Any]] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name: str = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/env/lib/python3.10/site-packages/click/utils.py b/env/lib/python3.10/site-packages/click/utils.py new file mode 100644 index 0000000..d536434 --- /dev/null +++ b/env/lib/python3.10/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO[t.Any]: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO[t.Any]: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict". This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return filename + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no effect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO[t.Any]) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/env/lib/python3.10/site-packages/distutils-precedence.pth b/env/lib/python3.10/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..6de4198 --- /dev/null +++ b/env/lib/python3.10/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'stdlib') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/INSTALLER b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/LICENSE.rst b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask-3.0.0.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/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/METADATA b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/METADATA new file mode 100644 index 0000000..b802e93 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 3.0.0 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Requires-Dist: Werkzeug>=3.0.0 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.1.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.6.2 +Requires-Dist: importlib-metadata>=3.6.0; python_version < '3.10' +Requires-Dist: asgiref>=3.2 ; extra == "async" +Requires-Dist: python-dotenv ; extra == "dotenv" +Project-URL: Changes, https://flask.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://flask.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/ +Project-URL: Source Code, https://github.com/pallets/flask/ +Provides-Extra: async +Provides-Extra: dotenv + +Flask +===== + +Flask is a lightweight `WSGI`_ web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around `Werkzeug`_ +and `Jinja`_ and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + +.. _WSGI: https://wsgi.readthedocs.io/ +.. _Werkzeug: https://werkzeug.palletsprojects.com/ +.. _Jinja: https://jinja.palletsprojects.com/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Flask + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + # save this as app.py + from flask import Flask + + app = Flask(__name__) + + @app.route("/") + def hello(): + return "Hello, World!" + +.. code-block:: text + + $ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Contributing +------------ + +For guidance on setting up a development environment and how to make a +contribution to Flask, see the `contributing guidelines`_. + +.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst + + +Donate +------ + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://flask.palletsprojects.com/ +- Changes: https://flask.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Flask/ +- Source Code: https://github.com/pallets/flask/ +- Issue Tracker: https://github.com/pallets/flask/issues/ +- Chat: https://discord.gg/pallets + diff --git a/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/RECORD b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/RECORD new file mode 100644 index 0000000..62f9c1b --- /dev/null +++ b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=4ZWUCb3mASkMqqVUHq0GeDd5wh_RcJuoP5RmZ5VRkos,250 +flask-3.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.0.0.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.0.0.dist-info/METADATA,sha256=02XP69VTiwn5blcRgHcyuSQ2cLTuJFV8FXw2x4QnxKo,3588 +flask-3.0.0.dist-info/RECORD,, +flask-3.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.0.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +flask-3.0.0.dist-info/entry_points.txt,sha256=bBP7hTOS5fz9zLtC7sPofBZAlMkEvBxu7KqS6l5lvc4,40 +flask/__init__.py,sha256=6xMqdVA0FIQ2U1KVaGX3lzNCdXPzoHPaa0hvQCNcfSk,2625 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-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__/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=voUkc9xk9B039AhVrU21GDpsQ6wqrr-NobqLx8fURfQ,59201 +flask/blueprints.py,sha256=zO8bLO9Xy1aVD92bDmzihutjVEXf8xdDaVfiy7c--Ck,3129 +flask/cli.py,sha256=PDwZCfPagi5GUzb-D6dEN7y20gWiVAg3ejRnxBKNHPA,33821 +flask/config.py,sha256=YZSZ-xpFj1iW1B1Kj1iDhpc5s7pHncloiRLqXhsU7Hs,12856 +flask/ctx.py,sha256=x2kGzUXtPzVyi2YSKrU_PV1AvtxTmh2iRdriJRTSPGM,14841 +flask/debughelpers.py,sha256=WKzD2FNTSimNSwCJVLr9_fFo1f2VlTWB5EZ6lmR5bwE,5548 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=ynEoMB7fdF5Y1P-ngxMjZDZWfrJ4St-9OGZZsTcUwx8,22992 +flask/json/__init__.py,sha256=pdtpoK2b0b1u7Sxbx3feM7VWhsI20l1yGAvbYWxaxvc,5572 +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=VBKSK75t3OsTvZ3N10B3Fsu7-NdpfrGYcl41goQJ3q8,7640 +flask/json/tag.py,sha256=ihb7QWrNEr0YC3KD4TolZbftgSPCuLk7FAvK49huYC0,8871 +flask/logging.py,sha256=VcdJgW4Axm5l_-7vXLQjRTL0eckaMks7Ya_HaoDm0wg,2330 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228 +flask/sansio/__pycache__/app.cpython-310.pyc,, +flask/sansio/__pycache__/blueprints.cpython-310.pyc,, +flask/sansio/__pycache__/scaffold.cpython-310.pyc,, +flask/sansio/app.py,sha256=nZWCFMOW8qK95Ck9UvDzxvswQr-coLJhIFaa_OVobCc,37977 +flask/sansio/blueprints.py,sha256=caskVI1Zf3mM5msevK5-tWy3VqX_A8mlB0KGNyRx5_0,24319 +flask/sansio/scaffold.py,sha256=-Cus0cVS4PmLof4qLvfjSQzk4AKsLqPR6LBpv6ALw3Y,30580 +flask/sessions.py,sha256=rFH2QKXG24dEazkKGxAHqUpAUh_30hDHrddhVYgAcY0,14169 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=EtL8CE5z2aefdR1I-TWYVNg0cSuXBqz_lvOGKeggktk,7538 +flask/testing.py,sha256=h7AinggrMgGzKlDN66VfB0JjWW4Z1U_OD6FyjqBNiYM,10017 +flask/typing.py,sha256=2pGlhSaZqJVJOoh-QdH-20QVzl2r-zLXyP8otXfCCs4,3156 +flask/views.py,sha256=V5hOGZLx0Bn99QGcM6mh5x_uM-MypVT0-RysEFU84jc,6789 +flask/wrappers.py,sha256=PhMp3teK3SnEmIdog59cO_DHiZ9Btn0qI1EifrTdwP8,5709 diff --git a/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/REQUESTED b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/WHEEL b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/entry_points.txt b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask-3.0.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/env/lib/python3.10/site-packages/flask/__init__.py b/env/lib/python3.10/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import typing as t + +from . import json as json +from .app import Flask as Flask +from .blueprints import Blueprint as Blueprint +from .config import Config as Config +from .ctx import after_this_request as after_this_request +from .ctx import copy_current_request_context as copy_current_request_context +from .ctx import has_app_context as has_app_context +from .ctx import has_request_context as has_request_context +from .globals import current_app as current_app +from .globals import g as g +from .globals import request as request +from .globals import session as session +from .helpers import abort as abort +from .helpers import flash as flash +from .helpers import get_flashed_messages as get_flashed_messages +from .helpers import get_template_attribute as get_template_attribute +from .helpers import make_response as make_response +from .helpers import redirect as redirect +from .helpers import send_file as send_file +from .helpers import send_from_directory as send_from_directory +from .helpers import stream_with_context as stream_with_context +from .helpers import url_for as url_for +from .json import jsonify as jsonify +from .signals import appcontext_popped as appcontext_popped +from .signals import appcontext_pushed as appcontext_pushed +from .signals import appcontext_tearing_down as appcontext_tearing_down +from .signals import before_render_template as before_render_template +from .signals import got_request_exception as got_request_exception +from .signals import message_flashed as message_flashed +from .signals import request_finished as request_finished +from .signals import request_started as request_started +from .signals import request_tearing_down as request_tearing_down +from .signals import template_rendered as template_rendered +from .templating import render_template as render_template +from .templating import render_template_string as render_template_string +from .templating import stream_template as stream_template +from .templating import stream_template_string as stream_template_string +from .wrappers import Request as Request +from .wrappers import Response as Response + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Flask 3.1. Use feature detection or" + " 'importlib.metadata.version(\"flask\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("flask") + + raise AttributeError(name) diff --git a/env/lib/python3.10/site-packages/flask/__main__.py b/env/lib/python3.10/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71db6720ac24408e7b543f7d548dfd34c847d4a1 GIT binary patch literal 2301 zcmb`I%W@k<6ozL;myu=5@>Rau%M=v{Qq@(|)JW5k#_qY$)3W1~ zvjKJ#D_#JWywdC_R(Syyu;D*#DN&g%Qu)`{fA@5sK7D!|S1M%#pFd82;!i+-Qe*s+ zL*rA!Fw?(G!|)B?6h>$=(JPlr83!1CoMYgDUM%2P3 zwxoF$yv&w0&w*FiispInDqGdO0A6Ejnis+AY+Z8=yumg!FM&7Nrsiev7TeOi0(O|A zc~um`ZMLm>P3(lbY*+I-c#rLA-T?2jea)NT19qT!3tVS)%?|jG9ctbNH&{dS4)};2 zY2F3jWA`-gf$y{Xn)k(nu*sU555O(f(p(20vt!MN;1hPDxgj2gr|eYo5%>{%1U~Uw z{_&4__JMDm8I6Z;sUjL?Ht9uCtUMLOQTpsH3WCi1c^XIfEqp1w^a3#PnHcay29ZLe z_%x2XK@T+NbrqMc>IbPS`F8`JQvZ4m|vUHBZ)X zhB13`GzmuIL6g?B-!EjRJWUZe+=ADRB~4!FBIG_`p~sc08{Bt84D@zr(sUqBu*0U-!%tmUz3O(14uV~w~Hpj#i zbmY@P47Y`z#a{eA_xx3dCv?Q6$_=cUQRcfr6bu)wj=WTPQt3DrM%JAmW=G2o z!_b5A{N0dhcPuwW?jt(WDu@y{ng~|yj`e=9{rp{}m7Wg|E6Yb-$g>Su8^U;F>RG898H?# ziL$xRhf!nsm$zM6X|!-=4_D5npNwwP7gD0$bMhV*&L-ZiARnRqyCFZq&)?s+`fN?Y6#>@i{h_w!S%g+Iq>`XPrI|`HQ&M6THQv%N91saM|uzWy5 z&on;F%C6fT&;j6pDUDfCT_;FQW~$7Pd2({NpOVTdE4N3l$y65gVBB!LDy6N*b<`_a z0?7#y`X?uDac; z9C$Mf!!S?x`(1E&PVY2y`ts%zfinwtcHl^WU=kGDF$TnLz(52MgsnGoVaS@c;zhX% zgQk_r!uaX~Oxwvn{r+IC6=A~7Rgl58(FaOvi{H@_x0FO_PKq`<%OoL{XOu;P)uqmL sIUP;LXp5S@DxMyBMi%#y+at!YpN!*Cb!j>?rNv3o+<#;JY!AA@AK0Tf8UO$Q literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..217c1ef7c50ee8b73a04abbc7e437b08c2cbe60f GIT binary patch literal 49697 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 Mc5)OSCf!&1&rvTX8~^|S literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4075d601897ef92055efdf139d4275e4bb89cb44 GIT binary patch literal 3437 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ÿU%oJ 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7355db673b5313143ec2ea57fe7e34946c07c911 GIT binary patch literal 12883 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 RS%VvN>ffw2U%Gthe*i_1E1LiS literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/ctx.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/ctx.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98a8e544d497b5a1f495c669626ab3d719ccc1dc GIT binary patch literal 14693 zcmdU0-ESP%b)T7?T`rg8QldUA$#y*QN61a2mEF`$!^n&gj3FtJMcZ8tcV@{Y zXLmMtW=U~D89`*g3evPMeMC* zb&^WGMt+$8TkC$*M8>z_8W%r@BA|S$>GZzhG9k}(=a^4GXtY# zu9_z6R$#4K@;kShli&7g9=~%zp*6KSC2j1W*qUCQmU=!YwPsdlP%n5>!EDQ3os)Vo zD7WTU=cPW4`mxnxQZEI^TMMfTQlCNn#Oevt@bgu=YpqNXI9Th zy&Rlvom)MJmQUX|R-d_Mc=O(|PYmzaeQWhu?|JW}cj^;+^-JCh-c#Ng)SmNR^v-!t zqvoLYjQ1>R=h5p+-gD^n9C|&EZ;p2!-_GOP3!Zh;sJ!$mQmJAlGj6*b#%|mU+tCWX zm%AO$js4oLayuPg;mO=B<<|Xmx4wOAujBKXct>nBGg?3GXDnP2Lu^X-dXP)+Ru24DUD~nC805-z$=5Im84v| z(&=1{?_LYSbvKCIzXN5iIGw<4ww-W&%df{(=LeDRId0^*PTOtyQ3sTD8liHcI8>mX z1KPWe*Oj{4E;;ysWzht9l5twD=R59>+YH?G05!Jton@|Nd2M6O>8SATUOH#B>Ue%sSIu>Q zdD&Uq_V*SY>~BM_i0i$&>DRY0fsa9yEG>@Fyc_$N4`ca}-;UGK*d8P9_=-GsJdVzvUe@D{&en{5wX{(gOm)MLy9#@6JACDWhE9mFWchA?R-yF&J|WkV*le8SqF5yb zC8Hna+ij#RH%~jm29>0{gIW}ksmbFF^v7lP*3C6;ro|1!>^uwE1FWvUnZ`L>cmVYbU*a-YfetYLq&|JUN*^4*B_SZnqOA$zP z5%RX}Zurrq29MXJdVIIq*~2NVZTQduv8vVn08>TOsg^m5egl)f0ZJT{q=a0~+jLN>HX>=L7_oksv;?W~hoyM<9PMyOq*{%8#YuvCdoJ8436kv_7;0U0|PAvZMKuy z0_ETt&bL^CucAJ#Y-ejVxd1n0i;=lGZw@~~j|-^8 z(CnV^(7Xrz?ipQE9rsY%vbJ)+K&CIghBVOI0urKzk#n&qZ zMXy8@Uy_4IC>Av-Xy=oThw?jEX-efJ2m3!pW%Vis2=Eheq>@=QkHH6+u%mP&TN~}; zoOXf52^3fd9Tz1}#h&x2e*YZbAL+%Xn&QJ2XCxYtF=O}8?X*p`%%{o(l=A^*upxf_bk_Pp2hPlXkZlG2}MPw zcu3Sm7IdP7l0(!Lv7tAk=27rlMBk@q*kvOaOb$3TZay57*}Lb0p>sP_fp>mU?>6H^ zD^z~Q4j76d28x*jsSzWIb!>uoeO~Ok?HIvcDAQ>kqHnecaPDn5k@OARHsVx}r@bwf z6_&9c>Uawy$4)j5i6mo1h*X@E1kP>~K}a`dc#7am0#?m>*|N6R%{I6_m^zD>`%&PL z2=N;-&q}Ypc$9aGP956~+X#Nwg)AP!Q3x}(CQw8_Qid?P5cD1Yf)jNS5F_+OFzY%y z!(^&f@@g6fO6%3x8(sJ|Enf$2XKH%-bl_S>+9)YN2>rGP)pMDB|A@ty=~y_r^a#x& zditePMawcR(|$agw@q~gj}A+5H9P+kkA9Bf=rUSnNB^hB13+HGNB@Cwkb7wS)cDl+ z)NEK@&a*!$-ZNu+-+W-+XGoEEmody0FfRc7GY}QwbISHn6`_wQK@M`Y-c<_DpKxc4 z+DA2qaAh}C+jKZ7CeDWP{dVBTnc8SUkkZjOdPZJqpKLL}Q^3#89wk%D)e#sHF9iR zg|giXXyM4wXA6js!nuOm&C}@C>mZ-rR5c?{s6XG59)j`C>;WeSF0N!@nOT+saSP3@ERPGIbqZ_!YuM$(WJ23=$In_w5 z#m^(^?^`$3aoqbK`jqtB;7*y*>!>_1{v4>r13?WQz!%szn(({-+Wa%~HXL6MxQA`r z&zbN6UNNFGyQW4!?f?hrV>D1;U&BbrjNgvB%CALx?K=HpS8YJaZSV3od@9jzqUrjM zPBN8($p47`65TUsl;Y~1vN#-PUgIZy4J35 zvqm>7dFJzG`3tm&=%kj;WO}xkFIy#BUFQIF8b>IL?|pAwkeE!xLcP)-x7Mp*J#6csxU?F&neX7i7+syC-It z-dOD7%(&hTtUJIy5laU4sqJgF0XP#LhI^L=mDwxpvWbGr(BKOWkXxq#Y*@yLngJ9Q z3@du-fV$i6Bgd&nHtdSkfip%#z15PpUi}_u62NO3Ii}Psh@RR_K%z@TJulFcQS`kp zV9~7**$DU*>NUb+6I?EKsb)RkW@XipNqDHSCO@Uz=s%8n1>Qs0Tvgqd-+x{w+X9k<;#a+%<)hg~2RsjDqB zFJ+F*ve15cEoJT+0m1Cq##%+v4zcRSn{6oO|A#zF_ciLtlSBLr5m?AAF2V22rAd1K z>q7MvXrjK4IOOLIl;H`4HRCe&PtYnFQh8Q=_w!Va`VQV!tlmGv``?ZnF^bD{hL+bR z47;Y!Eci{A1b%3iKa!=Uq5~~*=ZKiWe!C8#8z1Th2?Zo_pd~Ph^h`5CnHz$EAyg9O zNsxfxDAfRy=#)C_pi>{Cm`JC2ZU{qX-p#-EX*8wYokXL4;*Y9-B=L8qpZGiL6}@RD z{`>+`eCH(jhlHQ^v{&}#@w|wn9#efb(tb}toj;qDt{|7EQyw%hcFp|X91iTIgc~5W=k28-Og2}4m1spjHJgCWwv3>pY8G@HfHg-z zJlHu6S`q#rh*v|Yp)1q@lQY6V&E8;%gn9<16|^I zwGEv}t%)K_%nd*^NGHePHe3-kL=|T}kAxL>(#@0cOfC(X!*xmvRx5boSVQb1We{R8DV(gUbU3?Sxf=-`e z6Mat5CNntDu~GK8`UvUvnoEZ&OSi97is}X?Rd2B1K|wCkkJSuoNC~z*%_6MMP_M8U z3n^_zHNU}&h{s~VI%D?chqlbONzT7pKRo%S8~ObtewKWq1DSou=MsK|5`T$G@1+bL z^~`Nco!JLf5L+(90Fxdf&OB=XYBIL+2L+}|Or+N0se|G}lcVo_YIWxFY|=1;@Pb^&cUCpvX>Xy7eM=|-l_M(&JogARe>vi z8t-u1z}ZzH)8zx!RGp>6*-U%!$Q_y$bqifqD)UJWzK&)GK|XL|FG`9a9^?imT)g7b zh#`p;gPdB7>)AQ3{Oc>#O@0SViJ9w?Gm-DW|CW@*qnd@unokTHIX zmk}{l%PIq%WscVRanV{Zi;wXG$lw?tgEMxoJj`{ZP$<{ghjntAoc)Zaecw1R9>VD- z7?>qy-^cTbA~s#C!38AZJ%fQhqns5@+w7ejnz7$R(+gKa{KFZRsh}m(B%?q-i50IO zo*cPjl1U?n&OWSDB4y1w6?yr|$ExyMVMJ3DGWD8l7w3UTzkM=4l zrnuENSP;xn-(+!yhpPncV~EyW=ZbN*y$~rirh}(EtVI(KT|{7F-1?|fw&2udf(ntQw{Kp%?%={k6S|3D7qWQaP7|0?>P&q*)W$wWUaf;= zhm3I0lWv4WS6)-$B1o_YtR+q3qJbQWwyxvhAfwyXb4_bUSO6bj7y@Y#(0i=p`z>^h|69LLl>{BUT;Rd{@%v zBmqEe+)5IB8EEBtcVoj>B3b=;gbeGNS+Enhz=X}hWm{XzR=GyPMKQ%oLugH8f2z*S zW(&8q6q(MM$W&QMJ!n#d7(7ZcSOJM(gX{ze;yl71>;+)!JK-)MNTqKDWTfh&50OK7 zA#*o1yb*-V;RxD?m4{sgd@lphWhuNqwhkwQbK`ChtzPP8t_<{PGL=exV)GtKGL`Q8 zFjEPc!I(+`!NU{77Xs6_1D#u^@0NXN`e|ZmGolBmq~2-{=~dh|qSs0baxcd;>wd15 z+lQ}Fvpw-!d((JNAI~OiR?FWu+NW)JG<&#ga4&Bfz0y9t5W7~qZQOwkx|jbr--fr# z-@E26o}kzCKGJNpl6b;1QqK0RRb@`Q5Oe94Q#aS%io$j>!!pfBs$DEyeV@e&3vMwv z&iod_1Q@aOB4#qhW4`G}YLBhH#e%*hvathCxyz?A9vda5KV&+@YS7M9VG$z-mBLgJ z+25jBz(31eFw4O2ia)j<7c4xnOIGix8zYMQ$u2cnA#C6zARB+^EF!zj5%C}?(v$vT-a?+1v$%X(lDlmOf=g5F~gG*D*MgwXG z=O{}@3_#>J{kp65FVt2&Mv}NcMivTdCsbCXwX|HZ&CokcF2{pw`(lfTHyP$RUF1c8 zrKLbR7K(lMM;hHabp}w>?Y<4+WRrsO?4IT5`#Q3P8*&r#mFnQG2-@7DCP{;s44@zE z8f0M}WN?$n4?@>tC`%6Eek&qdSHp;$4UHCbVdEltW*O!IZ{R?W%6BD?yGZ(6A$u=QoXEbkl2bAvhEnf9MBm{Npu=a+*${pk z{|f)zJ258il+6*(8h*<_<1mcqEkLv(>YnLYKbKVehZJ@Tx`w5V>xa150lkvnt3ao+b5(Q}A*GqgT^t<4*yy_?6Kqqy2s4NEuf!CV(TH50u zAOh2*gh;ex&m!(TazN;C4??36C}|2~ z@qh`#@TU)87>LHZ(f}9kS-qS4mRd?7hLcZ%7-HVzEqXX0_j54gIWGr7FYV{=&f}clHZlu0R+x-x%>u z45(q>1`Gj*0OgbhBX}&oz#P$pIrfjt@w3Tu;J6pv8IT7EhBhpjs_(mWh)BBabpf6b zr$7&QP?=P^F8<&^YghW2{gW@CAg<)o9TnBw_nsNqO!U7o=&-fso_vgV026bQu>7RFq&kNxn`ObftG}*H_y;zq^s8m3z;D zRs*zWj9x%|)CZ6|^&yJNy!wcBIbjl5{|Ud=SkPP~Cx-EzbfjboH-~w(R69~~CW(dW zpxk9m49q%eP@dv^-Qi$!b>QkM(|O5|vD1<&sD6uyZ{8BmX% z;y-1J9vV>~oI}&bNi5=oW>}E@xcHl+&kK)x3uC$!A>Pe^1qyhzgk#1G%p{TPS0{a=;c4s z7~<=dsl+DUrLi139Z3#0Gb!-SeVC%S%s)>g<*Rt{4`ekJ0! z8yRAiFilJf=cCe(&Y(hY$~ucbIQg&Axzfo}sr+o|rIKAPDz*apcA2BR#zNN3TK1G@ zK|f^;Ndakbf%O-8qqEV)B{SUUR2Cj3GpWwpaaE+`q|*u|W}Hlm+C$hhSc$ zD3ZyEzJlq;TH4u3jKpdnW=-=H+K^M4lBuY<0be)L2(O^`bGPoi_g3xdJ8xb6?)8;x z15PEy)L2Jqj$MoCwTDR2A5wqFLNwDnYgbrYXTf}-B*X;F6H-m0bW*&mZ?(P-Y8w$n leAXyJV`%Jn*1|tQk!Q_9S}WM)Tz*tBr{?Tz1wKfP#Kf2WtjR}C+3TNYElM}b?MrPhFLGDc-PwKpB^a5r@a zwapsp99~PkL4C7s%3kUZ8k-GfU9)(d`wuMci>6rEb2nS4Y49d$nqpBjQL}`a1>QnU z3-8Y6F}}!`9$1^l`6+&aFF$ZMPw>-xg|DKt%-eVXW`r)ww(z#?<-nMg88UjUGoqSeuMnn>J_IAWi0!D<5Uz z-cZC^@Q<=2&bfG3%3K!P*P}!U9wb>XOruz+V5cvn2zKxvWjav#Km=W(wUB|J9)T3Y zT-JXe!csGo`5O6q@@O1&rZ z0R(DJx80*A0UzPiw*s@cEtJ|paI-Ihgo`LhRG|Bj4iX*2QD%fXl=)qJ3!yC_Ecn%rDo&s?% zQMzqpH%JCT?+!5*)bh|EB+ufH7+Gl%@gVO7X9uHHC&NhU4%!Z0Bjr5{i%8;rFc48T zm4B93%Zl?%i%i32$YiucgFymQ;h2}2+{0{`qq3V_Y*6*{QObkap@}S}b-negzp=*Fr}YWbIH^7MvBj)AHc9sp+W=^|FkAV^ zF75XDlHGe^SaK0v%f@Ja&?%0x^k>Id zy4!h@m0mO)ij0@eKy6WLCDLA5pXx{H+!niKi$(|skp?=b(&>(RWzEd`^!@=$)u!M> zEOiFA7V~Y__WtdD<@zU?%WV9i{MB){cZR0@XF%;LBe5rbT z1COWI0|-=FhT&O!Q*_cEE6zN3TGMP}&67S2)1Vt+m|URSD|CC6ZgU{5N_6OQ2{-Z< zin{ui%Y3)BY-(dv9Jxr*a6OB8pIJS|0RRvDP4_d)1?s_^-E#FR1b+p_b3GrCtGF(B zB7xV%U(IQYd$Aaj;gSW)xdSqo7r-k3?s`EK$f`4JzUpm2YR6bm9E}vA+Y?;_YH*nk zO&!d=pTnTxgmS(+Rk6O&7gY_?7a0uNw89byFRs0N^IY(gcQ0R|ZXbMj^QRwd+z6r! zaD+(|{PRc!V_1hzLL-JEk}a1fUc6WIWjypdVu! z;0e-Uz|%pkgEx2I)B`YU4;lAPTeofb%Gf!m@j5}LDfv{=-kx<(=Zyn@>^ua_5~YFc zn;XUI_S?Z#^0oMwrq4`cMtEK?I)3;# z8olxa)8U~HL7s_r@jt;0nEq^=K;`GG`y3q&X~~mQG7ez2``M-eK_6h#atAyJ@~NN; zh(s$k8bu&7r7=J^9RCsZ&9ij(xjNjI1SV^Z^2Bt;aNe(UMlvnynb--b;CCY>OsPSx zCn3v_1VUv^jlfPSJ3dXLxzfPJH|e8;@nnF~BUU!TFovL27#=ckGXK}{Gl1r?rtLBh z5cZ84!5P5Jqx*_i1pkM%&Y}Km;H6xg&K!$0oy~60rj416cah&l=|5>5gnlf9`~Zc|0hZfr!me2cWB@Y{d}17X&cyJJu^rOW!4p4f9Ww3^{1kuwkRU&} zb?XRQz;@tEKm-S2cD8T1Rm|oUSu8bR#sY<={t8{513}PSp{RqM68Fyg;-41cjomEdUEZ>LL3C zfZ|%(-hGt;xR_NOAG6OP@w-gE_*+Z6pQF{DeNY3Cc>pWxx8NHS``7jk+nGAKx;%$5 z%Y{RdFZ~(+lq>jV{7tz;;1L2kV$lUjC#9OdgyEV~X+24!WMa*h9qLI&a7f#~i`N_Y z88T$ECHys^=cM)aSGH~c+rMxBt62a43G1-Vtks@&vNWYUKU>BlRxN3+_@!4#{5q|Q zblbO9n0ylj3WaKh?^j!yJ8x{&*tVCa9A{-3S9|Wd35`pG z+xJgd#kWH~8VtiUj}WecT=w!Ob~xwDkJ)E( zZoq9H2``C!(x-Pw*EDDa@gfQ-_Z@_iNXtwRM^9?nlB*hSVB6;Ih|S8V2jm-_i=cDf zubfGJ;!hgd9s9ZlO>6Vo*x&Y`8}_7`y=dy|sK3NL)ccsHZoVTF-LIjAs~cl~k4>83 zSIx1<8>>j|eBttiaT9t7U52hNjO%8`=463d@z!`@7SP_gIc{KmmhADxNh@38OL%Xb zwuUJ`hPnKGXVMzGyz!<*K{EOtAGhXxU*abwi}>n*>HW@pT{dj)g~?*JK)r6e^1n^} z$yxolW~A}ucu{_7zPyOw+U6_ON=?lwwKb(vretlm4i@?8gQYoJBhk<@XTynG6uL23aGGu>3O4(y+sgqJ?8m!5$64 zFPhz1CJR~~eCIJ+ljL+t_PyeTb+E-<;)<0@QUqSqgX$`LMA;^EE9$)*D+#_+_!nS+ zXn(OVeiIE}yBJ(8&YGkO1_O1SuP8Qg0x|n81^yVIeY3dmNhC82upU&-9I1tBYJ?#M z91R^dv(A$Rvk}|HdsQlCR$=&Qn&-FCX*3K>E(h5b5Yr*zQ*dq)Sr@X*w&o1=i7@0_ zkV5gpAb3C8#R@4qz!Ppl5tE1uK&5BWo#j4~tv(I`u0hC4#ajVLun78E57m07%4xNS zFnysF5)39i){gT*XFjLuygD0Fm8`jTOj3MOIh@A4RoM{PXh7}(v(R^A!3)WN(taj; zCkf?Bmm+CN0i@xomB|BKwzh->paAitp{z^tzo@xCo4WMjzpyi{897i%t_l0x9b#oA)8!Mp zQI)*wTWQ`!zQr6GJOGkSN#34A?9ye0lndFMv4*mBIL&J^neug75CN}Y--Z;JQ!@)b oB(}L<+5i9m literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ea5f1b44e06f5dff2ecf209e3a53d5c5b5717fa GIT binary patch literal 1594 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 B4Nm|7 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af6e346769ad38b58bab5fde61c5e58943ebdba8 GIT binary patch literal 2557 zcmZuzU2oh(6!mz$pWV$@(^5)-L25}?3f`hhAg!VZNRzfADwPsiu~4mN?eVS?uf3g_ zZMspYK&=D_i8o$&N*?c2*I%(+a23H3!Q>_I-Mds3vp>!?v%mC35s!L zSnX7a#fv*Nu>>on_{^~0sl!S+I2Tld+B4@V=`@1#!Avmw%<0T<`*4;wj!0*Y&mGRg zY$2FCB1gFA8^PIN5p2!|_LkMW@B%Y!5`BgxNvfEN(nQ{Yd2KWGS$tQdk0&okW>OaX z;h0MWZwsG}M!F=p8jIv*MY-GjvAX?*kFic(HcZyA@{p1s5hVdt15SsjRFsWIA{~i{DNeZ%si0B`&W1FEAzFb!9Qh_!m);I3qj_dE3Rfg4 z^HubSFVi^fQgO-CS&b(trRB9SJ#0GR1g2HJB= z)ZwMMz5J#%NQb=DV`3iwZ2^OJAUD~%x3$)~&wE?`fDidLU>EZi1Z%}nuQi&eL7H55 zKfKnGk>VeWn7_;VTxPkprn!zLdf{}wv#_;9rY+XQ4CYuudoEtiO#L>^TsyrqjeR8Z z^g=HOeg)*{1`H0YL+i-;37+4Q10vp2DY$^qH2Z&**sQzFg>z+IRZql#s+_Q-F5EKfkB6pq>T{PP@ZEd^PbUCj`EP!Xmfd-6pb*0Y}{&*x-FT+$K z#P)X=to_RaCc7p;H}`Z`V$>PA>K?mnZ#0W~{#5$9z>Uwg1uASFSP% zSPywqKA=~wngSArQ#{HmSBGgZj$ziuF_#jk+mw(m=vWCN{4d~Z2zVRbD(jFOSUdI+ z0nn|Tf>;3P9SQftBFJS4MO&2*fOhgNSgWWit{f0N5cWH;`6fpd;B*7~8nqEflCcF9 z<5)w0gCH6qO*jvDkgMD__~o`(P{zL=Y89sv7jo@rGo?h^gWztaJ6&VGl4*(A*~Jy) zm?7=`0dO|=dUDb#;JtC*!+zii>%}}+rZO)ePsG4G70!0R6nmw$H`YJ<@+NqPrWi@# zlZEcDG#e7nx-ChM+ij}3S$sg}KfSX|SrAZW@}7$OaW}oL?x^3HT{uqswwITNk?~V- zTAVz9R1Ki_drU??x(^woi~8EE>2mI)o|m>uaCizH?L8BuiwJy3@uoa-X5m zc^f3^tXOtd&>sBOxi=>Q=?BkO~2C>=FQE7wV)| Nubp#X&G~1h_%A{r*Af5# literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8592a4f53f4f9e2bfb626ec4f9c1dfb18700e027 GIT binary patch literal 13270 zcma)DTWlQHdEVKby>PjtsJpE=&BRF~Z6Yo0C^xW4YMG{NCKlz8bX;$m?hbc`Mk` z*h&EfZ7w}0lo|IJ+Pm%N$$6>;-gE@y=Qjf#_V3_sU3nufu8 z-p@Dl^0&}5@wea?yQOAH-kE;6TW*%6UPQgptVq4&FLbNTs?^J2aZX z1^4Hi72L15OYW7&X7ehZoOdqZ$p!Z+TD*Y!i_Rt7UwWKxzUZENoNHdgv&+sEJiFq) zh&G>b@;kZu)nAbgbt7K1d%YmCBQNNMTex4oH;C*#-@Rw|`(Ez=Pb!Wbxslg(S?Awj z&||&!y6xSFz=~?fZLn=lBh;6aC8217F&; z4-Q=Cdpq~HrWzOT`gV9+&&TC$_a_54jN;0+8}>0hx5GJ4{!HAwM*gj#;^vx$lLOC; zX2CU`nqxY}56s6#v*;F&N}yyVy>}LxWvAM#-~#nQjpewuI^E-4q3=*8w<5cnOgGX1g6sjhRX zHB?5qClEF#{}EYH7~bAJ^g>Iy`@Y+WLMu9St#*7jc26y@C+|3! zMqC}gzY7`{4&3Oe5u2gw??26{%NXU^k5>B zUd3o(9!0G%yfR72M%E-QKCu0P8=G5@o(|ilKh_JlggPszM7fdi*cgFA--aTBLisIq z9?$EB;_G@|UBVyr0t>EF7gt#0L|(!rlUd2%-Q7a#b9^ITn))Nw_0tzot5@SntJSl+ zZmR{Vwz`2c@L8|5T0a@se)6W=YB@m%k1Kr@U|G?rj24$dH;P;p7kchVT*1fQzUMk| z#qM+k5211tuU~XA@Hh=e!8~T3#~(2aS;xd5(UypyM5R8L$}>- z$nD*&xa{@32q5>Y7&Y$nPR9Z@CEb*4>OTG&Aw|l2T%xVk^Z7y&>H$hPT@KV0MkON zC34ehO{i-f@9yG~nN*Dn=J2IYnn_#$3dV&nQd1;O0Ypelh0?T%43IZJGCnePa_UQX zjA;pFZlE47wpu_;AY8ZAN)hEIUZ^j#7;9<+xA$-*#Hty?&&{7=)>~Y5+J|2ThDuc^ zXtEmh>YR~p{#6vi-Mos!72NJ z?fLZQ8kY5*Aa2AG{#bAVw6mRCK@YI0@s-2S`4DhS`;%_q;#m9WNgy8f4xXXL!PvCb zL8!=&xO99XH{|QHYSh>Yw#6fw@`Xq$D(rodtAa`dO?Yhli2*A={OK-6pMdK@FPp!$ z=XPw+0xLs{4ty~JiFvvMs3mgs&mD;idqe|7n~PSTf*CG&Sy|tc5XYLb1c-(IbU-=@4SrKit}~n zOU`xF&O6_5zT(_O?SgX)I`hqVCDE779=x!9yW`ql11Bg*+I9ER=hkU3fMI{&QV6_m z--q+ti|AAb3hptVD!1>W2TF~IeFA-Bk<9u!IrKV*7UVIsPF!_7bO#65DT#EOwDTh! zWW$K`K}tC<(KyOrfCyv$q@cp`{TiFCwc&5}AOaGhh;L*iFG4IQdvQ~wJ;3A@J(vf& z3(RqU;9JR3FkP8BhjoJ9^$0GJ#+S~a-8*nIk8P}n!5*Uq(1y_s+U~*2!YbxYO|J@r zBZ|>}6P)D-o&zPDjG=t**ahJehFN`oprf9|v-Ut$DrG_=p~Sulx_Vr3Bi7mp+a+LY z6Wv@)u@iK`RL43Rgpm~v_M|OUT@Nokv1i+H_%u4SBdg1hZ*5Jxs&rT7BjAaU`v#+} zo9Ug5R$r5T*p$CMykY(E=Kg%DXwrpNyUpMS!JLG++5?7X<&zYeS_x6R_OaXQ!4_n^ zrE~)Hi2rsbjxv3lAtUIW$S!4CrU#2aHYHL6V)Xlg${gmCKpkh0N<_r>KN)!Ne?=$Y zDJKR5va=71;W~-%rYf2}h|A zPAO!zlCj(X-);Oi0q-Q{q((WKte6bw2R

N&S6^XB)zaMnWXGuZc*uC*=VHSl`h+ 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2ab82ec90a2ad3fb629ef64ca3d5deedb51200f GIT binary patch literal 824 zcmY+C%Z}496hQ5!(?|N6K|Cb>po@+{vmGHM_9LVskSZk0ZEn-h#16ItGua}s;U{3p zFL{SpvEc()apTsb)RC;?n`>Vm+iEh23ASHX-{5bDkl)Rq-69;kB!rr;2nk7OP71oB zwBb(PDWX+G2}EDWsteukXG!#fu6mxjNPSOdNCQtjq@kxiQtWAfH1ae=8heV7CZ0w} zQ%_^0Su$CY`See-!#Q;$A*HgyW=a|y4sS#OrW6~fFDw*gE-WlG$OJSb_2V^cl@5VL zNT_ETK2~7t!dRg#CZ31DHj|mzVdPe-ixw9ewxjJ=>`Q*jnfs@07jP>H}=7VQ-hO*gIG+H#;ccjY`uT z7|2g7&(^HGvpXfPE}uVRCd2oD&ts3rYgkiYk1>C8m*t%sTo)>-a(F?ppm~bjn2bBU LDDK4c^qbQEsPquo literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17c913369b88a6e37ab0487968e373dee691cee1 GIT binary patch literal 7101 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 I9IG7uH}|jHMF0Q* literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3700ee798e6749234d0170a33112c26fb80bab65 GIT binary patch literal 9710 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 L0qtt-iP`@ECt;NL literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/app.py b/env/lib/python3.10/site-packages/flask/app.py new file mode 100644 index 0000000..d710cb9 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/app.py @@ -0,0 +1,1478 @@ +from __future__ import annotations + +import os +import sys +import typing as t +import weakref +from collections.abc import Iterator as _abc_Iterator +from datetime import timedelta +from inspect import iscoroutinefunction +from itertools import chain +from types import TracebackType +from urllib.parse import quote as _url_quote + +import click +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.routing import BuildError +from werkzeug.routing import MapAdapter +from werkzeug.routing import RequestRedirect +from werkzeug.routing import RoutingException +from werkzeug.routing import Rule +from werkzeug.serving import is_running_from_reloader +from werkzeug.wrappers import Response as BaseResponse + +from . import cli +from . import typing as ft +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import g +from .globals import request +from .globals import request_ctx +from .globals import session +from .helpers import get_debug_flag +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import send_from_directory +from .sansio.app import App +from .sansio.scaffold import _sentinel +from .sessions import SecureCookieSessionInterface +from .sessions import SessionInterface +from .signals import appcontext_tearing_down +from .signals import got_request_exception +from .signals import request_finished +from .signals import request_started +from .signals import request_tearing_down +from .templating import Environment +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: # pragma: no cover + from .testing import FlaskClient + from .testing import FlaskCliRunner + +T_shell_context_processor = t.TypeVar( + "T_shell_context_processor", bound=ft.ShellContextProcessorCallable +) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) + + +def _make_timedelta(value: timedelta | int | None) -> timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(App): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + default_config = ImmutableDict( + { + "DEBUG": None, + "TESTING": False, + "PROPAGATE_EXCEPTIONS": None, + "SECRET_KEY": None, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "SERVER_NAME": None, + "APPLICATION_ROOT": "/", + "SESSION_COOKIE_NAME": "session", + "SESSION_COOKIE_DOMAIN": None, + "SESSION_COOKIE_PATH": None, + "SESSION_COOKIE_HTTPONLY": True, + "SESSION_COOKIE_SECURE": False, + "SESSION_COOKIE_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "SEND_FILE_MAX_AGE_DEFAULT": None, + "TRAP_BAD_REQUEST_ERRORS": None, + "TRAP_HTTP_EXCEPTIONS": False, + "EXPLAIN_TEMPLATE_LOADING": False, + "PREFERRED_URL_SCHEME": "http", + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + } + ) + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class = Response + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface: SessionInterface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_url_path=static_url_path, + static_folder=static_folder, + static_host=static_host, + host_matching=host_matching, + subdomain_matching=subdomain_matching, + template_folder=template_folder, + instance_path=instance_path, + instance_relative_config=instance_relative_config, + root_path=root_path, + ) + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert ( + bool(static_host) == host_matching + ), "Invalid static_host/host_matching combination" + # Use a weakref to avoid creating a reference cycle between the app + # and the view function (see #3761). + self_ref = weakref.ref(self) + self.add_url_rule( + f"{self.static_url_path}/", + endpoint="static", + host=static_host, + view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950 + ) + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for + reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to + :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is + supported, valid values are "r" (or "rt") and "rb". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) + + def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Opens a resource from the application's instance folder + (:attr:`instance_path`). Otherwise works like + :meth:`open_resource`. Instance resources can also be opened for + writing. + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + return open(os.path.join(self.instance_path, resource), mode) + + def create_jinja_environment(self) -> Environment: + """Create the Jinja environment based on :attr:`jinja_options` + and the various Jinja-related methods of the app. Changing + :attr:`jinja_options` after this will have no effect. Also adds + Flask-related globals and filters to the environment. + + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + + .. versionadded:: 0.5 + """ + options = dict(self.jinja_options) + + if "autoescape" not in options: + options["autoescape"] = self.select_jinja_autoescape + + if "auto_reload" not in options: + auto_reload = self.config["TEMPLATES_AUTO_RELOAD"] + + if auto_reload is None: + auto_reload = self.debug + + options["auto_reload"] = auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=self.url_for, + get_flashed_messages=get_flashed_messages, + config=self.config, + # request, session and g are normally added with the + # context processor for efficiency reasons but for imported + # templates we also want the proxies in there. + request=request, + session=session, + g=g, + ) + rv.policies["json.dumps_function"] = self.json.dumps + return rv + + def create_url_adapter(self, request: Request | None) -> MapAdapter | None: + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + if not self.subdomain_matching: + subdomain = self.url_map.default_subdomain or None + else: + subdomain = None + + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config["SERVER_NAME"], + subdomain=subdomain, + ) + # We need at the very least the server name to be set for this + # to work. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + def raise_routing_exception(self, request: Request) -> t.NoReturn: + """Intercept routing exceptions and possibly do something else. + + In debug mode, intercept a routing redirect and replace it with + an error if the body will be discarded. + + With modern Werkzeug this shouldn't occur, since it now uses a + 308 status which tells the browser to resend the method and + body. + + .. versionchanged:: 2.1 + Don't intercept 307 and 308 redirects. + + :meta private: + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.routing_exception.code in {307, 308} + or request.method in {"GET", "HEAD", "OPTIONS"} + ): + raise request.routing_exception # type: ignore + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + 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[str | None] = (None,) + + # A template may be rendered outside a request context. + if request: + names = chain(names, reversed(request.blueprints)) + + # The values passed to render_template take precedence. Keep a + # copy to re-apply after all context functions. + orig_ctx = context.copy() + + for name in names: + if name in self.template_context_processors: + for func in self.template_context_processors[name]: + context.update(self.ensure_sync(func)()) + + context.update(orig_ctx) + + def make_shell_context(self) -> dict: + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {"app": self, "g": g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + def run( + self, + host: str | None = None, + port: int | None = None, + debug: bool | None = None, + load_dotenv: bool = True, + **options: t.Any, + ) -> None: + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :doc:`/deploying/index` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Ignore this call so that it doesn't start another server if + # the 'flask run' command is used. + if os.environ.get("FLASK_RUN_FROM_CLI") == "true": + if not is_running_from_reloader(): + click.secho( + " * Ignoring a call to 'app.run()' that would block" + " the current 'flask' CLI command.\n" + " Only call 'app.run()' in an 'if __name__ ==" + ' "__main__"\' guard.', + fg="red", + ) + + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, env var overrides existing value + if "FLASK_DEBUG" in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + server_name = self.config.get("SERVER_NAME") + sn_host = sn_port = None + + if server_name: + sn_host, _, sn_port = server_name.partition(":") + + if not host: + if sn_host: + host = sn_host + else: + host = "127.0.0.1" + + if port or port == 0: + port = int(port) + elif sn_port: + port = int(sn_port) + else: + port = 5000 + + options.setdefault("use_reloader", self.debug) + options.setdefault("use_debugger", self.debug) + options.setdefault("threaded", True) + + cli.show_server_banner(self.debug, self.name) + + from werkzeug.serving import run_simple + + try: + run_simple(t.cast(str, host), port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient: + """Creates a test client for this application. For information + about unit testing head over to :doc:`/testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from .testing import FlaskClient as cls + return cls( # type: ignore + self, self.response_class, use_cookies=use_cookies, **kwargs + ) + + def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner: + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from .testing import FlaskCliRunner as cls + + return cls(self, **kwargs) # type: ignore + + def handle_http_exception( + self, e: HTTPException + ) -> HTTPException | ft.ResponseReturnValue: + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionchanged:: 1.0.3 + ``RoutingException``, used internally for actions such as + slash redirects during routing, is not passed to error + handlers. + + .. versionchanged:: 1.0 + Exceptions are looked up by code *and* by MRO, so + ``HTTPException`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + return e + + handler = self._find_error_handler(e, request.blueprints) + if handler is None: + return e + return self.ensure_sync(handler)(e) + + def handle_user_exception( + self, e: Exception + ) -> HTTPException | ft.ResponseReturnValue: + """This method is called whenever an exception occurs that + should be handled. A special case is :class:`~werkzeug + .exceptions.HTTPException` which is forwarded to the + :meth:`handle_http_exception` method. This function will either + return a response value or reraise the exception with the same + traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the + bad key in debug mode rather than a generic bad request + message. + + .. versionadded:: 0.7 + """ + if isinstance(e, BadRequestKeyError) and ( + self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"] + ): + e.show_exception = True + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e, request.blueprints) + + if handler is None: + raise + + return self.ensure_sync(handler)(e) + + def handle_exception(self, e: Exception) -> Response: + """Handle an exception that did not have an error handler + associated with it, or that was raised from an error handler. + This always causes a 500 ``InternalServerError``. + + Always sends the :data:`got_request_exception` signal. + + If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug + mode, the error will be re-raised so that the debugger can + display it. Otherwise, the original exception is logged, and + an :exc:`~werkzeug.exceptions.InternalServerError` is returned. + + If an error handler is registered for ``InternalServerError`` or + ``500``, it will be used. For consistency, the handler will + always receive the ``InternalServerError``. The original + unhandled exception is available as ``e.original_exception``. + + .. versionchanged:: 1.1.0 + Always passes the ``InternalServerError`` instance to the + handler, setting ``original_exception`` to the unhandled + error. + + .. versionchanged:: 1.1.0 + ``after_request`` functions and other finalization is done + even for the default 500 response when there is no handler. + + .. versionadded:: 0.3 + """ + exc_info = sys.exc_info() + got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e) + propagate = self.config["PROPAGATE_EXCEPTIONS"] + + if propagate is None: + propagate = self.testing or self.debug + + if propagate: + # Re-raise if called with an active exception, otherwise + # raise the passed in exception. + if exc_info[1] is e: + raise + + raise e + + self.log_exception(exc_info) + server_error: InternalServerError | ft.ResponseReturnValue + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error, request.blueprints) + + if handler is not None: + server_error = self.ensure_sync(handler)(server_error) + + return self.finalize_request(server_error, from_error_handler=True) + + def log_exception( + self, + exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]), + ) -> None: + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error( + f"Exception on {request.path} [{request.method}]", exc_info=exc_info + ) + + def dispatch_request(self) -> ft.ResponseReturnValue: + """Does the request dispatching. Matches the URL and returns the + return value of the view or error handler. This does not have to + be a response object. In order to convert the return value to a + proper response object, call :func:`make_response`. + + .. versionchanged:: 0.7 + This no longer does the exception handling, this code was + moved to the new :meth:`full_dispatch_request`. + """ + req = request_ctx.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule: Rule = req.url_rule # type: ignore[assignment] + # if we provide automatic options for this URL and the + # request came with the OPTIONS method, reply automatically + if ( + getattr(rule, "provide_automatic_options", False) + and req.method == "OPTIONS" + ): + return self.make_default_options_response() + # otherwise dispatch to the handler for that endpoint + view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment] + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) + + def full_dispatch_request(self) -> Response: + """Dispatches the request and on top of that performs request + pre and postprocessing as well as HTTP exception catching and + error handling. + + .. versionadded:: 0.7 + """ + self._got_first_request = True + + try: + request_started.send(self, _async_wrapper=self.ensure_sync) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request( + self, + rv: ft.ResponseReturnValue | HTTPException, + from_error_handler: bool = False, + ) -> Response: + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send( + self, _async_wrapper=self.ensure_sync, response=response + ) + except Exception: + if not from_error_handler: + raise + self.logger.exception( + "Request finalizing failed with an error while handling an error" + ) + return response + + def make_default_options_response(self) -> Response: + """This method is called to create the default ``OPTIONS`` response. + This can be changed through subclassing to change the default + behavior of ``OPTIONS`` responses. + + .. versionadded:: 0.7 + """ + adapter = request_ctx.url_adapter + methods = adapter.allowed_methods() # type: ignore[union-attr] + rv = self.response_class() + rv.allow.update(methods) + return rv + + def ensure_sync(self, func: t.Callable) -> t.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: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, + ) -> str: + """Generate a URL to the given endpoint with the given values. + + This is called by :func:`flask.url_for`, and can be called + directly as well. + + An *endpoint* is the name of a URL rule, usually added with + :meth:`@app.route() `, and usually the same name as the + view function. A route defined in a :class:`~flask.Blueprint` + will prepend the blueprint's name separated by a ``.`` to the + endpoint. + + In some cases, such as email messages, you want URLs to include + the scheme and domain, like ``https://example.com/hello``. When + not in an active request, URLs will be external by default, but + this requires setting :data:`SERVER_NAME` so Flask knows what + domain to use. :data:`APPLICATION_ROOT` and + :data:`PREFERRED_URL_SCHEME` should also be configured as + needed. This config is only used when not in an active request. + + Functions can be decorated with :meth:`url_defaults` to modify + keyword arguments before the URL is built. + + If building fails for some reason, such as an unknown endpoint + or incorrect values, the app's :meth:`handle_url_build_error` + method is called. If that returns a string, that is returned, + otherwise a :exc:`~werkzeug.routing.BuildError` is raised. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it + is external. + :param _external: If given, prefer the URL to be internal + (False) or require it to be external (True). External URLs + include the scheme and domain. When not in an active + request, URLs are external by default. + :param values: Values to use for the variable parts of the URL + rule. Unknown keys are appended as query string arguments, + like ``?a=b&c=d``. + + .. versionadded:: 2.2 + Moved from ``flask.url_for``, which calls this method. + """ + req_ctx = _cv_request.get(None) + + if req_ctx is not None: + url_adapter = req_ctx.url_adapter + blueprint_name = req_ctx.request.blueprint + + # If the endpoint starts with "." and the request matches a + # blueprint, the endpoint is relative to the blueprint. + if endpoint[:1] == ".": + if blueprint_name is not None: + endpoint = f"{blueprint_name}{endpoint}" + else: + endpoint = endpoint[1:] + + # When in a request, generate a URL without scheme and + # domain by default, unless a scheme is given. + if _external is None: + _external = _scheme is not None + else: + app_ctx = _cv_app.get(None) + + # If called by helpers.url_for, an app context is active, + # use its url_adapter. Otherwise, app.url_for was called + # directly, build an adapter. + if app_ctx is not None: + url_adapter = app_ctx.url_adapter + else: + url_adapter = self.create_url_adapter(None) + + if url_adapter is None: + raise RuntimeError( + "Unable to build URLs outside an active request" + " without 'SERVER_NAME' configured. Also configure" + " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as" + " needed." + ) + + # When outside a request, generate a URL with scheme and + # domain by default. + if _external is None: + _external = True + + # It is an error to set _scheme when _external=False, in order + # to avoid accidental insecure URLs. + if _scheme is not None and not _external: + raise ValueError("When specifying '_scheme', '_external' must be True.") + + self.inject_url_defaults(endpoint, values) + + try: + rv = url_adapter.build( # type: ignore[union-attr] + endpoint, + values, + method=_method, + url_scheme=_scheme, + force_external=_external, + ) + except BuildError as error: + values.update( + _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external + ) + return self.handle_url_build_error(error, endpoint, values) + + if _anchor is not None: + _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@") + rv = f"{rv}#{_anchor}" + + return rv + + def make_response(self, rv: ft.ResponseReturnValue) -> Response: + """Convert the return value from a view function to an instance of + :attr:`response_class`. + + :param rv: the return value from the view function. The view function + must return a response. Returning ``None``, or the view ending + without returning, is not allowed. The following types are allowed + for ``view_rv``: + + ``str`` + A response object is created with the string encoded to UTF-8 + as the body. + + ``bytes`` + A response object is created with the bytes as the body. + + ``dict`` + A dictionary that will be jsonify'd before being returned. + + ``list`` + A list that will be jsonify'd before being returned. + + ``generator`` or ``iterator`` + A generator that returns ``str`` or ``bytes`` to be + streamed as the response. + + ``tuple`` + Either ``(body, status, headers)``, ``(body, status)``, or + ``(body, headers)``, where ``body`` is any of the other types + allowed here, ``status`` is a string or an integer, and + ``headers`` is a dictionary or a list of ``(key, value)`` + tuples. If ``body`` is a :attr:`response_class` instance, + ``status`` overwrites the exiting value and ``headers`` are + extended. + + :attr:`response_class` + The object is returned unchanged. + + other :class:`~werkzeug.wrappers.Response` class + The object is coerced to :attr:`response_class`. + + :func:`callable` + The function is called as a WSGI application. The result is + used to create a response object. + + .. versionchanged:: 2.2 + A generator will be converted to a streaming response. + A list will be converted to a JSON response. + + .. versionchanged:: 1.1 + A dict will be converted to a JSON response. + + .. versionchanged:: 0.9 + Previously a tuple was interpreted as the arguments for the + response object. + """ + + status = headers = None + + # unpack tuple returns + if isinstance(rv, tuple): + len_rv = len(rv) + + # a 3-tuple is unpacked directly + if len_rv == 3: + rv, status, headers = rv # type: ignore[misc] + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv + else: + rv, status = rv # type: ignore[assignment,misc] + # other sized tuples are not allowed + else: + raise TypeError( + "The view function did not return a valid response tuple." + " The tuple must have the form (body, status, headers)," + " (body, status), or (body, headers)." + ) + + # the body must not be None + if rv is None: + raise TypeError( + f"The view function for {request.endpoint!r} did not" + " return a valid response. The function either returned" + " None or ended without a return statement." + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, _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 preprocess_request(self) -> ft.ResponseReturnValue | None: + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + names = (None, *reversed(request.blueprints)) + + for name in names: + if name in self.url_value_preprocessors: + for url_func in self.url_value_preprocessors[name]: + url_func(request.endpoint, request.view_args) + + for name in names: + if name in self.before_request_funcs: + for before_func in self.before_request_funcs[name]: + rv = self.ensure_sync(before_func)() + + if rv is not None: + return rv + + return None + + def process_response(self, response: Response) -> Response: + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = request_ctx._get_current_object() # type: ignore[attr-defined] + + for func in ctx._after_request_functions: + response = self.ensure_sync(func)(response) + + for name in chain(request.blueprints, (None,)): + if name in self.after_request_funcs: + for func in reversed(self.after_request_funcs[name]): + response = self.ensure_sync(func)(response) + + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + + return response + + def do_teardown_request( + self, exc: BaseException | None = _sentinel # type: ignore + ) -> None: + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for name in chain(request.blueprints, (None,)): + if name in self.teardown_request_funcs: + for func in reversed(self.teardown_request_funcs[name]): + self.ensure_sync(func)(exc) + + request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def do_teardown_appcontext( + self, exc: BaseException | None = _sentinel # type: ignore + ) -> None: + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for func in reversed(self.teardown_appcontext_funcs): + self.ensure_sync(func)(exc) + + appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def app_context(self) -> AppContext: + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ: 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 app.test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from .testing import EnvironBuilder + + builder = EnvironBuilder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app(self, environ: 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: BaseException | None = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: # noqa: B001 + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if "werkzeug.debug.preserve_context" in environ: + environ["werkzeug.debug.preserve_context"](_cv_app.get()) + environ["werkzeug.debug.preserve_context"](_cv_request.get()) + + if error is not None and self.should_ignore_error(error): + error = None + + ctx.pop(error) + + def __call__(self, environ: 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/env/lib/python3.10/site-packages/flask/blueprints.py b/env/lib/python3.10/site-packages/flask/blueprints.py new file mode 100644 index 0000000..3a37a2c --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/blueprints.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +from .globals import current_app +from .helpers import send_from_directory +from .sansio.blueprints import Blueprint as SansioBlueprint +from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for + reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to + :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is + supported, valid values are "r" (or "rt") and "rb". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) diff --git a/env/lib/python3.10/site-packages/flask/cli.py b/env/lib/python3.10/site-packages/flask/cli.py new file mode 100644 index 0000000..dda266b --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/cli.py @@ -0,0 +1,1068 @@ +from __future__ import annotations + +import ast +import importlib.metadata +import inspect +import os +import platform +import re +import sys +import traceback +import typing as t +from functools import update_wrapper +from operator import itemgetter + +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 + + flask_version = importlib.metadata.version("flask") + werkzeug_version = importlib.metadata.version("werkzeug") + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {flask_version}\n" + f"Werkzeug {werkzeug_version}", + color=ctx.color, + ) + ctx.exit() + + +version_option = click.Option( + ["--version"], + help="Show the Flask version.", + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True, +) + + +class ScriptInfo: + """Helper object to deal with Flask applications. This is usually not + necessary to interface with as it's used internally in the dispatching + to click. In future versions of Flask this object will most likely play + a bigger role. Typically it's created automatically by the + :class:`FlaskGroup` but you can also manually create it and pass it + onwards as click object. + """ + + def __init__( + self, + app_import_path: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: bool = True, + ) -> None: + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path + #: Optionally a function that is passed the script info to create + #: the instance of the application. + self.create_app = create_app + #: A dictionary with arbitrary data that can be associated with + #: this script info. + self.data: dict[t.Any, t.Any] = {} + self.set_debug_flag = set_debug_flag + self._loaded_app: Flask | None = None + + def load_app(self) -> Flask: + """Loads the Flask app (if not yet loaded) and returns it. Calling + this multiple times will just result in the already loaded app to + be returned. + """ + if self._loaded_app is not None: + return self._loaded_app + + if self.create_app is not None: + app = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, maxsplit=1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(import_name, None, raise_if_not_found=False) + + if app: + 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, + ) + + +run_command.params.insert(0, _debug_option) + + +@click.command("shell", short_help="Run a shell in the app context.") +@with_appcontext +def shell_command() -> None: + """Run an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to its configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + + banner = ( + f"Python {sys.version} on {sys.platform}\n" + f"App: {current_app.import_name}\n" + f"Instance: {current_app.instance_path}" + ) + ctx: dict = {} + + # Support the regular Python interpreter startup script if someone + # is using it. + startup = os.environ.get("PYTHONSTARTUP") + if startup and os.path.isfile(startup): + with open(startup) as f: + eval(compile(f.read(), startup, "exec"), ctx) + + ctx.update(current_app.make_shell_context()) + + # Site, customize, or startup script can set a hook to call when + # entering interactive mode. The default one sets up readline with + # tab and history completion. + interactive_hook = getattr(sys, "__interactivehook__", None) + + if interactive_hook is not None: + try: + import readline + from rlcompleter import Completer + except ImportError: + pass + else: + # rlcompleter uses __main__.__dict__ by default, which is + # flask.__main__. Use the shell context instead. + readline.set_completer(Completer(ctx).complete) + + interactive_hook() + + code.interact(banner=banner, local=ctx) + + +@click.command("routes", short_help="Show the routes for the app.") +@click.option( + "--sort", + "-s", + type=click.Choice(("endpoint", "methods", "domain", "rule", "match")), + default="endpoint", + help=( + "Method to sort routes by. 'match' is the order that Flask will match routes" + " when dispatching a request." + ), +) +@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.") +@with_appcontext +def routes_command(sort: str, all_methods: bool) -> None: + """Show all registered routes with endpoints and methods.""" + rules = list(current_app.url_map.iter_rules()) + + if not rules: + click.echo("No routes were registered.") + return + + ignored_methods = set() if all_methods else {"HEAD", "OPTIONS"} + host_matching = current_app.url_map.host_matching + has_domain = any(rule.host if host_matching else rule.subdomain for rule in rules) + rows = [] + + for rule in rules: + row = [ + rule.endpoint, + ", ".join(sorted((rule.methods or set()) - ignored_methods)), + ] + + if has_domain: + row.append((rule.host if host_matching else rule.subdomain) or "") + + row.append(rule.rule) + rows.append(row) + + headers = ["Endpoint", "Methods"] + sorts = ["endpoint", "methods"] + + if has_domain: + headers.append("Host" if host_matching else "Subdomain") + sorts.append("domain") + + headers.append("Rule") + sorts.append("rule") + + try: + rows.sort(key=itemgetter(sorts.index(sort))) + except ValueError: + pass + + rows.insert(0, headers) + widths = [max(len(row[i]) for row in rows) for i in range(len(headers))] + rows.insert(1, ["-" * w for w in widths]) + template = " ".join(f"{{{i}:<{w}}}" for i, w in enumerate(widths)) + + for row in rows: + click.echo(template.format(*row)) + + +cli = FlaskGroup( + name="flask", + help="""\ +A general utility script for Flask applications. + +An application to load must be given with the '--app' option, +'FLASK_APP' environment variable, or with a 'wsgi.py' or 'app.py' file +in the current directory. +""", +) + + +def main() -> None: + cli.main() + + +if __name__ == "__main__": + main() diff --git a/env/lib/python3.10/site-packages/flask/config.py b/env/lib/python3.10/site-packages/flask/config.py new file mode 100644 index 0000000..5f921b4 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/config.py @@ -0,0 +1,347 @@ +from __future__ import annotations + +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.Callable | None = 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 | os.PathLike, defaults: dict | None = None + ) -> None: + super().__init__(defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name: str, silent: bool = False) -> bool: + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError( + f"The environment variable {variable_name!r} is not set" + " and as such configuration could not be loaded. Set" + " this variable and make it point to a configuration" + " file" + ) + return self.from_pyfile(rv, silent=silent) + + def from_prefixed_env( + self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + ) -> bool: + """Load any environment variables that start with ``FLASK_``, + dropping the prefix from the env key for the config key. Values + are passed through a loading function to attempt to convert them + to more specific types than strings. + + Keys are loaded in :func:`sorted` order. + + The default loading function attempts to parse values as any + valid JSON type, including dicts and lists. + + Specific items in nested dicts can be set by separating the + keys with double underscores (``__``). If an intermediate key + doesn't exist, it will be initialized to an empty dict. + + :param prefix: Load env vars that start with this prefix, + separated with an underscore (``_``). + :param loads: Pass each string value to this function and use + the returned value as the config value. If any error is + raised it is ignored and the value remains a string. The + default is :func:`json.loads`. + + .. versionadded:: 2.1 + """ + prefix = f"{prefix}_" + len_prefix = len(prefix) + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + # Change to key.removeprefix(prefix) on Python >= 3.9. + key = key[len_prefix:] + + if "__" not in key: + # A non-nested key, set directly. + self[key] = value + continue + + # Traverse nested dictionaries with keys separated by "__". + current = self + *parts, tail = key.split("__") + + for part in parts: + # If an intermediate dict does not exist, create it. + if part not in current: + current[part] = {} + + current = current[part] + + current[tail] = value + + return True + + def from_pyfile(self, filename: str | os.PathLike, silent: bool = False) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: object | str) -> None: + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, str): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_file( + self, + filename: str | os.PathLike, + load: t.Callable[[t.IO[t.Any]], t.Mapping], + silent: bool = False, + text: bool = True, + ) -> bool: + """Update the values in the config from a file that is loaded + using the ``load`` parameter. The loaded data is passed to the + :meth:`from_mapping` method. + + .. code-block:: python + + import json + app.config.from_file("config.json", load=json.load) + + import tomllib + app.config.from_file("config.toml", load=tomllib.load, text=False) + + :param filename: The path to the data file. This can be an + absolute path or relative to the config root path. + :param load: A callable that takes a file handle and returns a + mapping of loaded data from the file. + :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` + implements a ``read`` method. + :param silent: Ignore the file if it doesn't exist. + :param text: Open the file in text or binary mode. + :return: ``True`` if the file was loaded successfully. + + .. versionchanged:: 2.3 + The ``text`` parameter was added. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename, "r" if text else "rb") as f: + obj = load(f) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + + return self.from_mapping(obj) + + def from_mapping( + self, mapping: t.Mapping[str, t.Any] | None = None, **kwargs: t.Any + ) -> bool: + """Updates the config like :meth:`update` ignoring items with + non-upper keys. + + :return: Always returns ``True``. + + .. versionadded:: 0.11 + """ + mappings: dict[str, t.Any] = {} + if mapping is not None: + mappings.update(mapping) + mappings.update(kwargs) + for key, value in mappings.items(): + if key.isupper(): + self[key] = value + return True + + def get_namespace( + self, namespace: str, lowercase: bool = True, trim_namespace: bool = True + ) -> dict[str, t.Any]: + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in self.items(): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace) :] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self) -> str: + return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/env/lib/python3.10/site-packages/flask/ctx.py b/env/lib/python3.10/site-packages/flask/ctx.py new file mode 100644 index 0000000..b37e4e0 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/ctx.py @@ -0,0 +1,440 @@ +from __future__ import annotations + +import contextvars +import sys +import typing as t +from functools import update_wrapper +from types import TracebackType + +from werkzeug.exceptions import HTTPException + +from . import typing as ft +from .globals import _cv_app +from .globals import _cv_request +from .signals import appcontext_popped +from .signals import appcontext_pushed + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sessions import SessionMixin + from .wrappers import Request + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals: + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + # Define attr methods to let mypy know this is a namespace object + # that has arbitrary attributes. + + def __getattr__(self, name: str) -> t.Any: + try: + return self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def __setattr__(self, name: str, value: t.Any) -> None: + self.__dict__[name] = value + + def __delattr__(self, name: str) -> None: + try: + del self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def get(self, name: str, default: t.Any | None = None) -> t.Any: + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name: str, default: t.Any = _sentinel) -> t.Any: + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raising a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name: str, default: t.Any = None) -> t.Any: + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item: str) -> bool: + return item in self.__dict__ + + def __iter__(self) -> t.Iterator[str]: + return iter(self.__dict__) + + def __repr__(self) -> str: + ctx = _cv_app.get(None) + if ctx is not None: + return f"" + return object.__repr__(self) + + +def after_this_request(f: ft.AfterRequestCallable) -> 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: 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, _async_wrapper=self.app.ensure_sync) + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the app context.""" + try: + if len(self._cv_tokens) == 1: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + ctx = _cv_app.get() + _cv_app.reset(self._cv_tokens.pop()) + + if ctx is not self: + raise AssertionError( + f"Popped wrong app context. ({ctx!r} instead of {self!r})" + ) + + appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync) + + def __enter__(self) -> AppContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + +class RequestContext: + """The request context contains per-request information. The Flask + app creates and pushes it at the beginning of the request, then pops + it at the end of the request. It will create the URL adapter and + request object for the WSGI environment provided. + + Do not attempt to use this class directly, instead use + :meth:`~flask.Flask.test_request_context` and + :meth:`~flask.Flask.request_context` to create this object. + + When the request context is popped, it will evaluate all the + functions registered on the application for teardown execution + (:meth:`~flask.Flask.teardown_request`). + + The request context is automatically popped at the end of the + request. When using the interactive debugger, the context will be + restored so ``request`` is still accessible. Similarly, the test + client can preserve the context after the request ends. However, + teardown functions may already have closed some resources such as + database connections. + """ + + def __init__( + self, + app: Flask, + environ: dict, + request: Request | None = None, + session: SessionMixin | None = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + request.json_module = app.json + self.request: Request = request + self.url_adapter = None + try: + self.url_adapter = app.create_url_adapter(self.request) + except HTTPException as e: + self.request.routing_exception = e + self.flashes: list[tuple[str, str]] | None = None + self.session: SessionMixin | None = session + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions: list[ft.AfterRequestCallable] = [] + + self._cv_tokens: list[tuple[contextvars.Token, AppContext | None]] = [] + + def copy(self) -> RequestContext: + """Creates a copy of this request context with the same request object. + This can be used to move a request context to a different greenlet. + Because the actual request object is the same this cannot be used to + move a request context to a different thread unless access to the + request object is locked. + + .. versionadded:: 0.10 + + .. versionchanged:: 1.1 + The current session object is used instead of reloading the original + data. This prevents `flask.session` pointing to an out-of-date object. + """ + return self.__class__( + self.app, + environ=self.request.environ, + request=self.request, + session=self.session, + ) + + def match_request(self) -> None: + """Can be overridden by a subclass to hook into the matching + of the request. + """ + try: + result = self.url_adapter.match(return_rule=True) # type: ignore + self.request.url_rule, self.request.view_args = result # type: ignore + except HTTPException as e: + self.request.routing_exception = e + + def push(self) -> None: + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _cv_app.get(None) + + if app_ctx is None or app_ctx.app is not self.app: + app_ctx = self.app.app_context() + app_ctx.push() + else: + app_ctx = None + + self._cv_tokens.append((_cv_request.set(self), app_ctx)) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session(self.app, self.request) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + # Match the request URL after loading the session, so that the + # session is available in custom URL converters. + if self.url_adapter is not None: + self.match_request() + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + clear_request = len(self._cv_tokens) == 1 + + try: + if clear_request: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_request(exc) + + request_close = getattr(self.request, "close", None) + if request_close is not None: + request_close() + finally: + ctx = _cv_request.get() + token, app_ctx = self._cv_tokens.pop() + _cv_request.reset(token) + + # get rid of circular dependencies at the end of the request + # so that we don't require the GC to be active. + if clear_request: + ctx.request.environ["werkzeug.request"] = None + + if app_ctx is not None: + app_ctx.pop(exc) + + if ctx is not self: + raise AssertionError( + f"Popped wrong request context. ({ctx!r} instead of {self!r})" + ) + + def __enter__(self) -> RequestContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__} {self.request.url!r}" + f" [{self.request.method}] of {self.app.name}>" + ) diff --git a/env/lib/python3.10/site-packages/flask/debughelpers.py b/env/lib/python3.10/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..e836004 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/debughelpers.py @@ -0,0 +1,160 @@ +from __future__ import annotations + +import typing as t + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + + +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: App, 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, App): + src_info = f"application {srcobj.import_name!r}" + elif isinstance(srcobj, Blueprint): + src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})" + else: + src_info = repr(srcobj) + + info.append(f"{idx + 1:5}: trying loader of {src_info}") + + for line in _dump_loader_info(loader): + info.append(f" {line}") + + if triple is None: + detail = "no match" + else: + detail = f"found ({triple[1] or ''!r})" + total_found += 1 + info.append(f" -> {detail}") + + seems_fishy = False + if total_found == 0: + info.append("Error: the template could not be found.") + seems_fishy = True + elif total_found > 1: + info.append("Warning: multiple loaders returned a match for the template.") + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append( + " The template was looked up from an endpoint that belongs" + f" to the blueprint {blueprint!r}." + ) + info.append(" Maybe you did not place a template in the right folder?") + info.append(" See https://flask.palletsprojects.com/blueprints/#templates") + + app.logger.info("\n".join(info)) diff --git a/env/lib/python3.10/site-packages/flask/globals.py b/env/lib/python3.10/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/globals.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +import typing as t +from contextvars import ContextVar + +from werkzeug.local import LocalProxy + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .ctx import _AppCtxGlobals + from .ctx import AppContext + from .ctx import RequestContext + from .sessions import SessionMixin + from .wrappers import Request + + +_no_app_msg = """\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +the current application. To solve this, set up an application context +with app.app_context(). See the documentation for more information.\ +""" +_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx") +app_ctx: AppContext = LocalProxy( # type: ignore[assignment] + _cv_app, unbound_message=_no_app_msg +) +current_app: Flask = LocalProxy( # type: ignore[assignment] + _cv_app, "app", unbound_message=_no_app_msg +) +g: _AppCtxGlobals = LocalProxy( # type: ignore[assignment] + _cv_app, "g", unbound_message=_no_app_msg +) + +_no_req_msg = """\ +Working outside of request context. + +This typically means that you attempted to use functionality that needed +an active HTTP request. Consult the documentation on testing for +information about how to avoid this problem.\ +""" +_cv_request: ContextVar[RequestContext] = ContextVar("flask.request_ctx") +request_ctx: RequestContext = LocalProxy( # type: ignore[assignment] + _cv_request, unbound_message=_no_req_msg +) +request: Request = LocalProxy( # type: ignore[assignment] + _cv_request, "request", unbound_message=_no_req_msg +) +session: SessionMixin = LocalProxy( # type: ignore[assignment] + _cv_request, "session", unbound_message=_no_req_msg +) diff --git a/env/lib/python3.10/site-packages/flask/helpers.py b/env/lib/python3.10/site-packages/flask/helpers.py new file mode 100644 index 0000000..13a5aa2 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/helpers.py @@ -0,0 +1,623 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import lru_cache +from functools import update_wrapper + +import werkzeug.utils +from werkzeug.exceptions import abort as _wz_abort +from werkzeug.utils import redirect as _wz_redirect + +from .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 + + +def get_debug_flag() -> bool: + """Get whether debug mode should be enabled for the app, indicated by the + :envvar:`FLASK_DEBUG` environment variable. The default is ``False``. + """ + val = os.environ.get("FLASK_DEBUG") + return bool(val and val.lower() not in {"0", "false", "no"}) + + +def get_load_dotenv(default: bool = True) -> bool: + """Get whether the user has disabled loading default dotenv files by + setting :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load + the files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get("FLASK_SKIP_DOTENV") + + if not val: + return default + + return val.lower() in ("0", "false", "no") + + +def stream_with_context( + generator_or_function: ( + t.Iterator[t.AnyStr] | t.Callable[..., t.Iterator[t.AnyStr]] + ) +) -> t.Iterator[t.AnyStr]: + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) # type: ignore + 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() + + # 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: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, +) -> str: + """Generate a URL to the given endpoint with the given values. + + This requires an active request or application context, and calls + :meth:`current_app.url_for() `. See that method + for full documentation. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it is + external. + :param _external: If given, prefer the URL to be internal (False) or + require it to be external (True). External URLs include the + scheme and domain. When not in an active request, URLs are + external by default. + :param values: Values to use for the variable parts of the URL rule. + Unknown keys are appended as query string arguments, like + ``?a=b&c=d``. + + .. versionchanged:: 2.2 + Calls ``current_app.url_for``, allowing an app to override the + behavior. + + .. versionchanged:: 0.10 + The ``_scheme`` parameter was added. + + .. versionchanged:: 0.9 + The ``_anchor`` and ``_method`` parameters were added. + + .. versionchanged:: 0.9 + Calls ``app.handle_url_build_error`` on build errors. + """ + return current_app.url_for( + endpoint, + _anchor=_anchor, + _method=_method, + _scheme=_scheme, + _external=_external, + **values, + ) + + +def redirect( + location: str, code: int = 302, Response: type[BaseResponse] | None = None +) -> BaseResponse: + """Create a redirect response object. + + If :data:`~flask.current_app` is available, it will use its + :meth:`~flask.Flask.redirect` method, otherwise it will use + :func:`werkzeug.utils.redirect`. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + :param Response: The response class to use. Not used when + ``current_app`` is active, which uses ``app.response_class``. + + .. versionadded:: 2.2 + Calls ``current_app.redirect`` if available instead of always + using Werkzeug's default ``redirect``. + """ + if current_app: + return current_app.redirect(location, code=code) + + return _wz_redirect(location, code=code, Response=Response) + + +def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given + status code. + + If :data:`~flask.current_app` is available, it will call its + :attr:`~flask.Flask.aborter` object, otherwise it will use + :func:`werkzeug.exceptions.abort`. + + :param code: The status code for the exception, which must be + registered in ``app.aborter``. + :param args: Passed to the exception. + :param kwargs: Passed to the exception. + + .. versionadded:: 2.2 + Calls ``current_app.aborter`` if available instead of always + using Werkzeug's default ``abort``. + """ + if current_app: + current_app.aborter(code, *args, **kwargs) + + _wz_abort(code, *args, **kwargs) + + +def get_template_attribute(template_name: str, attribute: str) -> t.Any: + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, attribute) + + +def flash(message: str, category: str = "message") -> None: + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get("_flashes", []) + flashes.append((category, message)) + session["_flashes"] = flashes + app = current_app._get_current_object() # type: ignore + message_flashed.send( + app, + _async_wrapper=app.ensure_sync, + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> list[str] | list[tuple[str, str]]: + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :doc:`/patterns/flashing` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: filter of categories to limit return values. Only + categories in the list will be returned. + """ + flashes = request_ctx.flashes + if flashes is None: + flashes = session.pop("_flashes") if "_flashes" in session else [] + request_ctx.flashes = flashes + if category_filter: + flashes = list(filter(lambda f: f[0] in category_filter, flashes)) + if not with_categories: + return [x[1] for x in flashes] + return flashes + + +def _prepare_send_file_kwargs(**kwargs: t.Any) -> dict[str, t.Any]: + if kwargs.get("max_age") is None: + kwargs["max_age"] = current_app.get_send_file_max_age + + kwargs.update( + environ=request.environ, + use_x_sendfile=current_app.config["USE_X_SENDFILE"], + response_class=current_app.response_class, + _root_path=current_app.root_path, # type: ignore + ) + return kwargs + + +def send_file( + path_or_file: os.PathLike | str | t.BinaryIO, + mimetype: str | None = None, + as_attachment: bool = False, + download_name: str | None = None, + conditional: bool = True, + etag: bool | str = True, + last_modified: datetime | int | float | None = None, + max_age: None | (int | t.Callable[[str | None], int | None]) = None, +) -> Response: + """Send the contents of a file to the client. + + The first argument can be a file path or a file-like object. Paths + are preferred in most cases because Werkzeug can manage the file and + get extra information from the path. Passing a file-like object + requires that the file is opened in binary mode, and is mostly + useful when building a file in memory with :class:`io.BytesIO`. + + Never pass file paths provided by a user. The path is assumed to be + trusted, so a user could craft a path to access a file you didn't + intend. Use :func:`send_from_directory` to safely serve + user-requested paths from within a directory. + + If the WSGI server sets a ``file_wrapper`` in ``environ``, it is + used, otherwise Werkzeug's built-in wrapper is used. Alternatively, + if the HTTP server supports ``X-Sendfile``, configuring Flask with + ``USE_X_SENDFILE = True`` will tell the server to send the given + path, which is much more efficient than reading it in Python. + + :param path_or_file: The path to the file to send, relative to the + current working directory if a relative path is given. + Alternatively, a file-like object opened in binary mode. Make + sure the file pointer is seeked to the start of the data. + :param mimetype: The MIME type to send for the file. If not + provided, it will try to detect it from the file name. + :param as_attachment: Indicate to a browser that it should offer to + save the file instead of displaying it. + :param download_name: The default name browsers will use when saving + the file. Defaults to the passed file name. + :param conditional: Enable conditional and range responses based on + request headers. Requires passing a file path and ``environ``. + :param etag: Calculate an ETag for the file, which requires passing + a file path. Can also be a string to use instead. + :param last_modified: The last modified time to send for the file, + in seconds. If not provided, it will try to detect it from the + file path. + :param max_age: How long the client should cache the file, in + seconds. If set, ``Cache-Control`` will be ``public``, otherwise + it will be ``no-cache`` to prefer conditional caching. + + .. versionchanged:: 2.0 + ``download_name`` replaces the ``attachment_filename`` + parameter. If ``as_attachment=False``, it is passed with + ``Content-Disposition: inline`` instead. + + .. versionchanged:: 2.0 + ``max_age`` replaces the ``cache_timeout`` parameter. + ``conditional`` is enabled and ``max_age`` is not set by + default. + + .. versionchanged:: 2.0 + ``etag`` replaces the ``add_etags`` parameter. It can be a + string to use instead of generating one. + + .. versionchanged:: 2.0 + Passing a file-like object that inherits from + :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather + than sending an empty file. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionchanged:: 1.1 + ``filename`` may be a :class:`~os.PathLike` object. + + .. versionchanged:: 1.1 + Passing a :class:`~io.BytesIO` object supports range requests. + + .. versionchanged:: 1.0.3 + Filenames are encoded with ASCII instead of Latin-1 for broader + compatibility with WSGI servers. + + .. versionchanged:: 1.0 + UTF-8 filenames as specified in :rfc:`2231` are supported. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file + objects. If you want to use automatic MIME and etag support, + pass a filename via ``filename_or_fp`` or + ``attachment_filename``. + + .. versionchanged:: 0.12 + ``attachment_filename`` is preferred over ``filename`` for MIME + detection. + + .. versionchanged:: 0.9 + ``cache_timeout`` defaults to + :meth:`Flask.get_send_file_max_age`. + + .. versionchanged:: 0.7 + MIME guessing and etag support for file-like objects was + removed because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. + + .. versionchanged:: 0.5 + The ``add_etags``, ``cache_timeout`` and ``conditional`` + parameters were added. The default behavior is to add etags. + + .. versionadded:: 0.2 + """ + return werkzeug.utils.send_file( # type: ignore[return-value] + **_prepare_send_file_kwargs( + path_or_file=path_or_file, + environ=request.environ, + mimetype=mimetype, + as_attachment=as_attachment, + download_name=download_name, + conditional=conditional, + etag=etag, + last_modified=last_modified, + max_age=max_age, + ) + ) + + +def send_from_directory( + directory: os.PathLike | str, + path: 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. + try: + spec = importlib.util.find_spec(import_name) + + if spec is None: + raise ValueError + except (ImportError, ValueError): + loader = None + else: + loader = spec.loader + + # Loader does not exist or we're referring to an unloaded main + # module or a main module without path (interactive sessions), go + # with the current working directory. + if loader is None: + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +@lru_cache(maxsize=None) +def _split_blueprint_path(name: str) -> list[str]: + out: list[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/env/lib/python3.10/site-packages/flask/json/__init__.py b/env/lib/python3.10/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..f15296f --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/json/__init__.py @@ -0,0 +1,170 @@ +from __future__ import annotations + +import json as _json +import typing as t + +from ..globals import current_app +from .provider import _default + +if t.TYPE_CHECKING: # pragma: no cover + from ..wrappers import Response + + +def dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dumps() ` + method, otherwise it will use :func:`json.dumps`. + + :param obj: The data to serialize. + :param kwargs: Arguments passed to the ``dumps`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dumps``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.dumps(obj, **kwargs) + + kwargs.setdefault("default", _default) + return _json.dumps(obj, **kwargs) + + +def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dump() ` + method, otherwise it will use :func:`json.dump`. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: Arguments passed to the ``dump`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dump``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, will be + removed in Flask 2.1. + """ + if current_app: + current_app.json.dump(obj, fp, **kwargs) + else: + kwargs.setdefault("default", _default) + _json.dump(obj, fp, **kwargs) + + +def loads(s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.loads() ` + method, otherwise it will use :func:`json.loads`. + + :param s: Text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``loads`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.loads``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The data must be a + string or UTF-8 bytes. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.loads(s, **kwargs) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.load() ` + method, otherwise it will use :func:`json.load`. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``load`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.load``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The file must be text + mode, or binary mode with UTF-8 bytes. + """ + if current_app: + return current_app.json.load(fp, **kwargs) + + return _json.load(fp, **kwargs) + + +def jsonify(*args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. A dict or list returned from a view will be converted to a + JSON response automatically without needing to call this. + + This requires an active request or application context, and calls + :meth:`app.json.response() `. + + In debug mode, the output is formatted with indentation to make it + easier to read. This may also be controlled by the provider. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + + .. versionchanged:: 2.2 + Calls ``current_app.json.response``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 0.11 + Added support for serializing top-level arrays. This was a + security risk in ancient browsers. See :ref:`security-json`. + + .. versionadded:: 0.2 + """ + return current_app.json.response(*args, **kwargs) diff --git a/env/lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23ab773a6e9380813c9b340107a5fc1c5841e2f1 GIT binary patch literal 6008 zcmd5=&u<&Y73PwZMAMR-C~o{CjWbPpC<}Qh*+5Ycfl=47TQ{g2R7!%XD9GW?kXmVf zb!JJHfzVS=EzrNA1$ycK(Z6DEMNdBWrc=K+v%91vN{|gDFaeUYJ2P))-n{p{_q}*+ zty#h6KM(&Z|NXs6<-hbW|Eb~OXO)VhkI@hn;RKb?*>@ajSA*()&HUH*mqbm}gXM5# ze+7L@VmWAp*Y>YD6}fcSRG*-CCAc20?ysWvBe5pd|6Jc+6HIJ~_t07wKM?PWTWH-7 zAB#KUE?V!1PsE4f9$N2;>Tad=!mX%CLD#~g)RUXYQJ|w-4@8_g~ zpP-Re)M{EebPlV>m4V||j-7uxe{**6|M!}3()vHDP9zn5>mlW@gD2Gw@h-a&r8G-kRuv1|8ehgq$6*kd&ug}5}$60Wrr3^TAU z>-Ef*dN_8N1d@iB>&_Q*T{f0V`6NgL>qA|SvlC{wA}1nO2Y zjK@-3DCa>b=Lru24M}qsF{j#IZ)$cqIg zKvTw``m)dw^CR|*>=3HmzChl#yEUi!LhT+D0$KUB3SUVt4W^q+ai~M#lF_f^A4Wdy zHrHOcEu1Npe@xjRR&>6BKOA8muG<<>woST}ElChbrsb!k?t7Yn4>QZ;B zsv3Awgm(X`s15v`^xFqmS^7R;wG1 zd7D)S$;q|Ueg5KixU}DA^_@799sy4AA?z)|=jV6;_}nPK=hzuk0Y6oOA7CmF^0;~$ zg3gX<)wpvm5aAvKnz`e*(o}ekm$;$!YTaABL4}YZ&zb@2G zfY$dTuBPTnfVVJE()laEg$Qn<$YudyrJx+{PeB>ogCd{YX;}bK>v+iOgdgf1G!1U3 zchPFqENa}Ow*(yqIPA}R^mq$DZG5eJ-?|I;zU`Q|nWImx!?D>hU^ zytE>%ok=Aez77xmOqQYbyGSO2n2XCL6K3RVd#sst%4IcD2?_&nK;vUpkFS|XSix^= zB9ZUzsuPLQ0bcQw3j_QtYYRs@CFtU%6q{3=xd+p~C>Q(gQ-W6AWCGTamyA}e|5nv) za??ew`vE$BO|DB>LjBH7XQQg<-O0L%$%Y{8A~2upxauxOw;X==0(V4`!x2MN90JO| z#du0bzEnJ=fp6rUr<`+fprq3lf%1&KyjJ|9eZIBv&u;FDy>^!T?=9vpMEDlx=MOK) z&mXv3r6a#49GEnyfCI|NOF>~Qz(N7cd32^{MBnt_EK`Zg!?*ktB>e@Ebjs|D9C=31;ief<=@|j1EMn-7C3ss&LUTTD(+pb? z$WgGMV>vS~Y6(3eyr2yB=r%C{4GetG&=tc5dO5H5!K|l=bdg>PA5);bzz5RWbtuua zATjpkq)226c4wKf1!Q9Gm}H9?jE~Yd#9|(p=+tZ@9;Gaj(z;>Hr~@gJuX7XGLo;Vy z5+wy3-%Fte^Gaen*w)+$XajWdRwX2Bajl`)&!r%!82qS!l;;r>vOgL!YgVL3oFc(N zuvg^YI3TfIV_$wGifRC**dafn3WzaG$+b`1GR9%Ja1qfkJ>*lcbZwGxI*f{g0J6ZG zX_>MfVoNYjVZo4)#GrPdn>-+O9LebVSz1Y?)4PB3y8#rOwv#fo$5B*jf%Jy)1pz3|PeFO_V$+uNmL9}5Ay z$!jl$6&89m0WVJO2XZU}T)pB`om(H(oaXWjH(1^oL$it-E>o=uz>=F|3Ehdy6-S=DO`P|fD2O8VVvDClMJ%9|7f*{Nv5ZzhJR^>a6KEC1cf@1j6j~+mtT-#4KxeXq;U>dviEr|Y|6D8sUY4`xMMUg&f&t|OgMD1{RRPInYWLEjroy=F&lxpzFQ zhW{Ai2(Q6COg-Aa>AkPdOfe}=xMvF zPMGXVZ>Qsil9%DV;t*nXwaD?M8%9o}FQctSTa5a{u+4*#Cw}0Huw8d9`@TM9v?Y~8 zqXQ8-I17#-d+x}Orps!XO?OY{bf+iHPO$1okC)4K+-|=PiSD%Z7N84$XTyym)o6d* zqrN(isBeeCpp}ZE#b;}ixM$?U4_8Uh2Nr@BdA@V$;EJ#4H3p71AdBcqtySspTFHqT zLsz+dvW13od7n*W)9TI!nZjMq_sJGu0SeaOhK|bzB6Df*l8yFV>Fy}mtK%#m?zWv^ z0JTXcIdTgxfh=%*uQQ5dvVnTtxg%8whjWFHqS0_J)-UqHaSjty0p1fAl#E7d5Zmj) zKz7Lk(+{=D)2@)GEuj$^_sxmK@APjuOT(9NgVzRS1&s&Ra+Dy%g?NItXHHUc* z4Mo%UI%``&U#@jrHHJs6-BiK0>_*|*ySJ{a{X}+db+=%<8^PwLFW2PY&KfLrZMX{y z8oW?{{<*c#i{yo&+ud3)p`bR4Cx3<=J>>{C)d*v zaW3d=@8zTV<-u-T*tzSf%`nb|k=iE(l7NZt+xYo{fHyKeF>B`dx3{G7T%Q~k*yWPa z=q-upS#w(dcu50lPKLqs!gOMNs$@M>@1fzmlOc;&j9)~;+ zmmVX^T?IvJAMJU5YRq3xqCN6Ghn69f9zdFe(DVk9V3fVz~S1nNj=Y@myP{w zX}tW1@?taGn}^n%iPPDQWO$@~tHPWoD%R#=1k;Hl#@C$%4~wm>T8(L@??U z_LbW4lSfG+&oQV$-DHFZte89Zs%*jR^0&y0$>7runKYR)oAF6BV8X`4yl*}**o-YQ zV?w?0UyhQGqofNHQvqO~t?p4cINTy>UTTrwtSoDmdKzboZF*%b!G@!)i^TRC#d>Wysz&b{Sm1n%)Zi+0ti*XtkbEeWq15nQY~{CGcVkhn?wR|qv;LStg8(!^4w z2sm-i`~>I`Rwq_irBD;$?w%>E9ZQ{>m?C!?&nD*Z@d;5(dwu*eVh+dZx=Kjn`I-~C zJ2FhU18tHdt6g-}0T*>TLA3QbfxDs$yl-w}cPJS(W zqeC$pj3wG)0@7|n@+sHlaNKTZ;Mw;;03p#CFQ7o!=#2*5jHgiuXVrN<@EYnODh+z< z`=O?$nne4y0JMP^kk87OyLSVy_o)~X7S7U{8pRa9 zuJ>RmGvlFaEy`7=-6qNe4hjaB!KIivYf1oNc@%|0I5^@E!pDfiTQ-NeXCKtqg9qt; zoIJ=5OUH@et~e_61_BQv{*`#d#&i<7;t`YfmJX^AOrn(P4pFEMt5ampaWyk@W~KYW z)YM6sX&fLKrF7;`u}(+^U0FPNkeQ`p*6~szj?7RM<-%$nmxl#SVvf@TW-{F3e!}Zo zX{Mhc?OTV8OjhDBLjH7cC0esqP&}VVAsf8Ky6M}b3U7(ToD-ZNK3&M)3G;@3L_ozvH zmZJawU?(wcMSZ{38ZX|^&_nq%FvS_4CdVTfCs@rq(CzrLwiK5=xSP(+6h#_ECy9#! zNpRow0LfGxw*RLwFp?IFyJX^O64pR6nH0Q++VWF13>McL$xUkFr@ZR}dJgR@p3D74xK}-aua$-+dq2{i_82 z9W>Hn$889)nUl86-!oCzuw+r>E*W!%KuLqIbGYVF$|#_x$UUXzJf58rRk4U7M@5_# zE8-Yh3*wA8DIPP&q$T)8h=hJlQYiXmFyGgXffL7Q`vQ?+M9r!(^W z=z=#uwIC3UHUYej32DmWWTA-=UIN*DKe$V4AW==>nzJerYuM1JegQC;X2a-|5u!^y zZ6w8rBw0?MayPn^E^QEyW~j@FRYUa2cQ*uY_DMxpay`4`|)s*Ag?sdRlW~Td+p#56RRPy#C z+=945rn;2%Fx}DhGo+ppOe{oEBwK|G0Ww1EED=qp(+M)bq}Y>mv{$o9NrxPSBT!K{ z?0Q~X6T74*3{=$Gk-Jp0ON&Hl*^rzfVJcsvRBN*q>S7tXD&t;pc z72+~VZ^^lMtU?lIs2|ZRn^x4p?+iWM53JnrCp-@+*j39_vuduGO)SqPNHF6@D#NU z2#GrWj4x+#D}}?w!>elEQpDJOTp*7J^yMtXM`Jb%@r;jb@-tzM47E%?ww()4@)HYB zo|xG8ZIKf;`P!hsclgT!`yq|ZV`O2H;~d+j92*Rv_!;?XQIt5JnR9=E=ri?3a)xgp zpYc!(+Q8B&4RuluoY`?&s6BU(F`wf!DoG}~Tkc>Jr6x*}vZ;wDrb|M5Sr>AQq&I;* z27T1HT|cD!0@fsCXSC@coJt}+azJP*0Ha$|pCB23>@Jofr{q{u3A*KIOxs9_y3A77v(EUwt3d7qQ+3L z&X|QS$7c_NzSN}EiSxfB%rBA&P{)B<_NdYAc^%`AXp$maxTmXjzv5U<}y-E)&^sq$yjR+(s2l2vP zsdmP4v{|P=M(SK)VdK4<*IHNJymsa7>+5eo+3o;;N~y#1^&d`3cNN7)TcAoC};c!R}fAnKXwyc)rtTbMEXs;c|;o4rwQg)+VFYPQPJ3Crora4_h zj@UCzSNBljfOdeDgDkK~fFuZzAlN_(5F`R}3=klP90CN`Lk+!GKIKn$O0|;Ii~dY! zwl*vEX@9O$u9c-;LVdnAkNS)^>o0T`Yl~8!Lw%{XWM#gS@yg!(XBlt)o?SbF)`GW) z)}lIcFIzi`_L6r5?IY4YhW1hK7~03AeH`uM-ZN-FBkgC9W%dI@@kDaqbhq+@@+cJ&bdr z&30Idg27@6cNAJOgX6i8d(m0%MNT_%I_|EsuJ~B1=R57L6JV%zwtdWoOTaaE9w_I$z3uHlN6A>T-%_bsb=+PQm~F2(hEe3xT0*nZB?rHij_Rx{9j+XBgoE+e z{!#C#=sY>69Bf71bvxTWDRLvn^*nSWy8)j|1Ew_t-&alYKdip5J*Aa*wcU&wRfm5< z#|ygWBWKgykx2uNAobkAMJEi%y-f&37HWsi9p&6<`@ZA#I@`j`cBDF?Mx76-MXUFw>>Q`)OKlHGYPWV}1bJO`u8&AF1r&v*0|<=(@Px(|mXCy*b{E5jYeepb1MYFjmJYhI zdo~Ok!gjZ*u!m8$HJnZ_j7q>kx`+o*fa4s<)f$beh_e}Z>g9DmXl|{nINQ6?X3#B( zJh4#6F;Ko82Hh(6(C!F~QnAZ8!z!R)Wcdrph{}o#A&Bbr&<~=pUU%MhE}S1S;rzwQ zU<_ILwj-=Gd*FkfYB|kK)!e!eD!-LTYh+@M(JJccuG0o5sG3c6L1cQ-8QD{1e99=O zldPvtdh_NMM1rNE(Z&=gO=eu!soWA%f$kkb5eUz*PQ z(8-4CCXFJ@kBZtIg;BX1H?Cd9-@^A@z17?1bDL4LUFQ%qpg=lQ()!#s>*T3`Va1B` ze&Bjxlgp3(vS?hQTf2^m%G4~lHv0w~S}p6@aA?_D-pi?imwyYc!Yg?*pXF*(a2503 z0%}F?q_^lTp*D@$5$`B!CDe|2$5ERRH*hMRO3>K9`mP%)#{iZ_9?)uc+uaR^TIxWi zp$Ig!Nnj#82OnM=NWM`eokJw7_Df-;ojqqY=&Cpi1nZ-qBtAOn;kaOc8s|8=NfxC) z)_GkaFL)Bzv-UD|@Bxm@?pLm81s210VUruM9Naw(0F6<1=r(k9RUg5_6+6xmva*+l z8GQ=(9^YEt3_5Cg-PL^<&*cwva2p0UT>fzF%JN5QeGN+1QP+cw4PPy*?#{B`USBqd zeXaWHE6X9U{W9F;mb;nHJV=d z0B#J@I*XV*eu*=H(4Xp$H(AFn0w?55++%d(osKt4)Hou9gP?59yb14cAq>aexft%RnLgCp@|j zEa<8}i{}77_x^L}S z53Dxz$m*|+(qzy>iR|aU_<68eNF)29;=LwZj2e*S>Y#_iKs%~dY<-M-{1q0Hq>;r8 zAEHyxw2vmMV9+&F%PT=)? z)@SSWk9)44^i0+3UeLtt>477bZO8NV`iLv2*Y$H;^hFjz(RtP`uo!|&YSb0IgyNgH zLRLzdoRza@b0xc!!@qnvFa1q)js3D{U4or^^ad)a%^$P)^Ip-Lh6OL+r6RTY3*M|Z zhkHe@3|TJ5Q`g-M9u4~sQ4xdq>dSP$$yw^oW&m3sbp2g9p>^B{%1d2KeI!rDFc8MG z%7MJ=`aX_>#4}Gw@*LDN?6q3$yBL0_9c?;|dcAQ`0K##mk4l_iS^#oq6Gqv?8-+P9 zz{41g78drin0=Cb51^TRx#N#*3HPIyE=SL{LI*@)LW{{tGy@pV`>1eLo8)XP?X@>S?dWcD)Xb_%%GE z-(*2oD&TvV9kJJKl9 zfT{ocv-m4#^%W;Wse&N4UZ=iXxS;kh37Gsd7%UuZe5yN6Ifz0jbwx3OM5xyeTMI4$5X! zFt74Z!xCUM7Z*Rk3odoe5G~Gg+(sRW;YU2vq!?byJhWE9$=7jD|0;`fEQYiRCrSA( zF7aR`t6xr6pMW_!IZ}no3TaG#FVljGc=l(-J?nnvLFQ`a9$i3owMo@Te|)5X3uh)P zBqeQlj9W85vOghIt)IYyz<<~etUs|ow%5!Kada5KvXYJM>MOCe6P>~Iyzj<^D*vccm?GlFFvVkh*_-l;z*Qax z_i3*rrhT4~CDf+8IY?$9E<#VP_i#=#X3}<|uVf`PR?q0mC=z7F`AB9v$NLko^%LHI z7e&9EuKW~aJ))NzMb>0g5sWl|MAaku^9`b^_(_Th$npoBLJ$a_#-yCqeal8 zIAX*?aP<2aB>HdyI2!EwAdUtP7{Z4v7{}00)9IG1{=)w04(KxJ!e*^UMO3KER4K!8 zOMf5tMzA{Ay{19@LtL`$qSap-UFV=ZEKWr0moJVK6wsElnmtWiW4|m~ zmq3wz2bI*oy$5C+wtW=?cMyI#3SlBksC$2kD?uNXmy13HeR`Ff+-Jc?v8LbWoWgmC zDWgANF^(nu1Kj&_-d{suOpz@8|Ax??akA^2OpMUzWFtmMf0x6CN;rha57F_*xWmc+$CsaNxzI^$k=+J$06~ zNkmaO|CXH}q7c;_%zZ#L^+y~yNrpGk@t5rUZ5C`bagF`BgG=1htEk}gJ`F2if=K@*(pX-A??q1#eb^K8Sp{J}N6@5`whv0*;pIt`rBH=~Y^ zlRCnn3L#Aig7dtNFn`Za!l!uoHl0=HvVX_j4P}<$v7K>wd0kI~ii{b5!CtB<2s>X2 zgp~XhB82a%=J<&NOXgly4k|bd3tP0n36p z0~<~~4W_i0gz0_jft-{QM;d2g!gK?j6W1d+{{fe*H*1c%$$DP_ozsU+PjvnxI|ZFb z29T*@@`Lbvn}O9_~er+^Q522KAt zk)M>`KeO{)6!MP6We<@Z53&Lvo?!Q^+j#X$oN=7pRCgyXK!N=WE)iJ407RDf3gVi= z^AjhhxPHz~5f@*3(y0#$>rh+bVS<0+Bw|b0da8J4u+mk8#I7Sqor=i&B}GJ@P9%~d z`Zsoph~(WaS^5w$*%&M^7@Fgm!zQPA{+*ozz^8N(@{G0~dMF#Q_H&0#PXYbMVESVt zY@4i6hYG2MN&b}+iICVjAS7b^63yFfRQA6QsJtquDOFU{s-$Mr>_)LR=biTQUIFg| z<>{&EBD1>^dUk=bSLI9FTn&PvueS6lR6K$!m&?k#!eyl1`VP&?uk@gDJ_#M0b7 zXve^>Fjfw0FR4~n;;G>-(j*<)_aq05Fwr0joWy6DmUSa>3NF%SNS8>qQ6jX+67tlB zpb#>ObS#pN=_s$wFnt>ML7*P_KqjbCx6zJ5&+Q_DAM}_QPV-63#c|km%+x|6G`K@g zh9Hf`c9~svxPv5bsyrlOIr^o+w0zHO?7Jr~Kl^XW@n-+c34V3oT%Y!OZLdmgKJaXs z9jc}kGXh7OUx(o1e85cYFtj=L`c2iy;SwwMHB|WeU6(IBP-KX`V5!MOUCVS3Ajj-Lrqee z{%BqXly9QJbPwWVxxL)&%qRK1yl3?+eP+)NPwnNw32O(gEwVj(FOT?H_GdUG{Mg#d zv1bpdvArzDXY|+6&fdoy27N)8(&ndqkEO@{DI zU`ep8Ah+j2V^ZQ*M2}1^4QiCKyy|?!v^!E2=F}8XA(GIkeC5Eo(%*2QWOP#vQy|UQT<2QLX(4)|oC^sGDu~YtfYWtW)ZOMv<9ljXaz70T z*Sc+J?}61sYAYsPO6xEo506YQ6`m{;Y*(Ed=35L#eaDvNFn%Gxp_1kaw^b7#lQ>PL zA#s?TL`tK<+#o(iNH@>FBb23UbHeTI!51F9jRt3B)$Gie2~M!0Nw1T#02G>W+#0j) zoGr=Eq>`jwxqww+Bp4jzK4&w zHZG6@e6yLgbJna~LV48gpPI-6c|bQYc#IWeE{fqlup-GRGQ9i;hzeJ-{ns$1=$*+a zQg7tLBYq}C8K)nbNg5T5na)WNn#wkx(^Fk0lp5zO@rr#XS5Vt;$JQZ$yq=S?vWbi2kz z1gs55A4sN#oFlo*x*7ZY$X(XW-R8($)) zu{4WR5TB}?mi!VE#jPF_+DP~kNO1v28K5$@qPVaQ_w>f=nr2SoQ<|rhIL9-fyt>Av zVIW2`HxSR=QF^PddK*=K4y37aniz|7d}lF;7HX(Ll9T!}+~I~t;6I>0F1}^5-0uK8 lneZZtTxRyAA`WoLKT|_l&Mur?IJHp5zgb*M3+1Kq{{g|e>p1`b literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/json/provider.py b/env/lib/python3.10/site-packages/flask/json/provider.py new file mode 100644 index 0000000..3c22bc8 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/json/provider.py @@ -0,0 +1,216 @@ +from __future__ import annotations + +import dataclasses +import decimal +import json +import typing as t +import uuid +import weakref +from datetime import date + +from werkzeug.http import http_date + +if t.TYPE_CHECKING: # pragma: no cover + from ..sansio.app import App + from ..wrappers import Response + + +class JSONProvider: + """A standard set of JSON operations for an application. Subclasses + of this can be used to customize JSON behavior or use different + JSON libraries. + + To implement a provider for a specific library, subclass this base + class and implement at least :meth:`dumps` and :meth:`loads`. All + other methods have default implementations. + + To use a different provider, either subclass ``Flask`` and set + :attr:`~flask.Flask.json_provider_class` to a provider class, or set + :attr:`app.json ` to an instance of the class. + + :param app: An application instance. This will be stored as a + :class:`weakref.proxy` on the :attr:`_app` attribute. + + .. versionadded:: 2.2 + """ + + def __init__(self, app: App) -> None: + self._app = weakref.proxy(app) + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + :param obj: The data to serialize. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def dump(self, obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: May be passed to the underlying JSON library. + """ + fp.write(self.dumps(obj, **kwargs)) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + :param s: Text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + return self.loads(fp.read(), **kwargs) + + def _prepare_response_obj( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> t.Any: + if args and kwargs: + raise TypeError("app.json.response() takes either args or kwargs, not both") + + if not args and not kwargs: + return None + + if len(args) == 1: + return args[0] + + return args or kwargs + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. + + The :func:`~flask.json.jsonify` function calls this method for + the current application. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + return self._app.response_class(self.dumps(obj), mimetype="application/json") + + +def _default(o: t.Any) -> t.Any: + if isinstance(o, date): + return http_date(o) + + if isinstance(o, (decimal.Decimal, uuid.UUID)): + return str(o) + + if dataclasses and dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + + if hasattr(o, "__html__"): + return str(o.__html__()) + + raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable") + + +class DefaultJSONProvider(JSONProvider): + """Provide JSON operations using Python's built-in :mod:`json` + library. Serializes the following additional data types: + + - :class:`datetime.datetime` and :class:`datetime.date` are + serialized to :rfc:`822` strings. This is the same as the HTTP + date format. + - :class:`uuid.UUID` is serialized to a string. + - :class:`dataclasses.dataclass` is passed to + :func:`dataclasses.asdict`. + - :class:`~markupsafe.Markup` (or any object with a ``__html__`` + method) will call the ``__html__`` method to get a string. + """ + + default: t.Callable[[t.Any], t.Any] = staticmethod( + _default + ) # type: ignore[assignment] + """Apply this function to any object that :meth:`json.dumps` does + not know how to serialize. It should return a valid JSON type or + raise a ``TypeError``. + """ + + ensure_ascii = True + """Replace non-ASCII characters with escape sequences. This may be + more compatible with some clients, but can be disabled for better + performance and size. + """ + + sort_keys = True + """Sort the keys in any serialized dicts. This may be useful for + some caching situations, but can be disabled for better performance. + When enabled, keys must all be strings, they are not converted + before sorting. + """ + + compact: bool | None = None + """If ``True``, or ``None`` out of debug mode, the :meth:`response` + output will not add indentation, newlines, or spaces. If ``False``, + or ``None`` in debug mode, it will use a non-compact representation. + """ + + mimetype = "application/json" + """The mimetype set in :meth:`response`.""" + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON to a string. + + Keyword arguments are passed to :func:`json.dumps`. Sets some + parameter defaults from the :attr:`default`, + :attr:`ensure_ascii`, and :attr:`sort_keys` attributes. + + :param obj: The data to serialize. + :param kwargs: Passed to :func:`json.dumps`. + """ + kwargs.setdefault("default", self.default) + kwargs.setdefault("ensure_ascii", self.ensure_ascii) + kwargs.setdefault("sort_keys", self.sort_keys) + return json.dumps(obj, **kwargs) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON from a string or bytes. + + :param s: Text or UTF-8 bytes. + :param kwargs: Passed to :func:`json.loads`. + """ + return json.loads(s, **kwargs) + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with it. The response mimetype + will be "application/json" and can be changed with + :attr:`mimetype`. + + If :attr:`compact` is ``False`` or debug mode is enabled, the + output will be formatted to be easier to read. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + dump_args: dict[str, t.Any] = {} + + if (self.compact is None and self._app.debug) or self.compact is False: + dump_args.setdefault("indent", 2) + else: + dump_args.setdefault("separators", (",", ":")) + + return self._app.response_class( + f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype + ) diff --git a/env/lib/python3.10/site-packages/flask/json/tag.py b/env/lib/python3.10/site-packages/flask/json/tag.py new file mode 100644 index 0000000..91cc441 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/json/tag.py @@ -0,0 +1,314 @@ +""" +Tagged JSON +~~~~~~~~~~~ + +A compact representation for lossless serialization of non-standard JSON +types. :class:`~flask.sessions.SecureCookieSessionInterface` uses this +to serialize the session data, but it may be useful in other places. It +can be extended to support other types. + +.. autoclass:: TaggedJSONSerializer + :members: + +.. autoclass:: JSONTag + :members: + +Let's see an example that adds support for +:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so +to handle this we will dump the items as a list of ``[key, value]`` +pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to +identify the type. The session serializer processes dicts first, so +insert the new tag at the front of the order since ``OrderedDict`` must +be processed before ``dict``. + +.. code-block:: python + + from flask.json.tag import JSONTag + + class TagOrderedDict(JSONTag): + __slots__ = ('serializer',) + key = ' od' + + def check(self, value): + return isinstance(value, OrderedDict) + + def to_json(self, value): + return [[k, self.serializer.tag(v)] for k, v in iteritems(value)] + + def to_python(self, value): + return OrderedDict(value) + + app.session_interface.serializer.register(TagOrderedDict, index=0) +""" +from __future__ import annotations + +import typing as t +from base64 import b64decode +from base64 import b64encode +from datetime import datetime +from uuid import UUID + +from markupsafe import Markup +from werkzeug.http import http_date +from werkzeug.http import parse_date + +from ..json import dumps +from ..json import loads + + +class JSONTag: + """Base class for defining type tags for :class:`TaggedJSONSerializer`.""" + + __slots__ = ("serializer",) + + #: The tag to mark the serialized object with. If ``None``, this tag is + #: only used as an intermediate step during tagging. + key: str | None = None + + def __init__(self, serializer: TaggedJSONSerializer) -> None: + """Create a tagger for the given serializer.""" + self.serializer = serializer + + def check(self, value: t.Any) -> bool: + """Check if the given value should be tagged by this tag.""" + raise NotImplementedError + + def to_json(self, value: t.Any) -> t.Any: + """Convert the Python object to an object that is a valid JSON type. + The tag will be added later.""" + raise NotImplementedError + + def to_python(self, value: t.Any) -> t.Any: + """Convert the JSON representation back to the correct type. The tag + will already be removed.""" + raise NotImplementedError + + def tag(self, value: t.Any) -> t.Any: + """Convert the value to a valid JSON type and add the tag structure + around it.""" + return {self.key: self.to_json(value)} + + +class TagDict(JSONTag): + """Tag for 1-item dicts whose only key matches a registered tag. + + Internally, the dict key is suffixed with `__`, and the suffix is removed + when deserializing. + """ + + __slots__ = () + key = " di" + + def check(self, value: t.Any) -> bool: + return ( + isinstance(value, dict) + and len(value) == 1 + and next(iter(value)) in self.serializer.tags + ) + + def to_json(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {f"{key}__": self.serializer.tag(value[key])} + + def to_python(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {key[:-2]: value[key]} + + +class PassDict(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, dict) + + def to_json(self, value: t.Any) -> t.Any: + # JSON objects may only have string keys, so don't bother tagging the + # key here. + return {k: self.serializer.tag(v) for k, v in value.items()} + + tag = to_json + + +class TagTuple(JSONTag): + __slots__ = () + key = " t" + + def check(self, value: t.Any) -> bool: + return isinstance(value, tuple) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + def to_python(self, value: t.Any) -> t.Any: + return tuple(value) + + +class PassList(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, list) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + tag = to_json + + +class TagBytes(JSONTag): + __slots__ = () + key = " b" + + def check(self, value: t.Any) -> bool: + return isinstance(value, bytes) + + def to_json(self, value: t.Any) -> t.Any: + return b64encode(value).decode("ascii") + + def to_python(self, value: t.Any) -> t.Any: + return b64decode(value) + + +class TagMarkup(JSONTag): + """Serialize anything matching the :class:`~markupsafe.Markup` API by + having a ``__html__`` method to the result of that method. Always + deserializes to an instance of :class:`~markupsafe.Markup`.""" + + __slots__ = () + key = " m" + + def check(self, value: t.Any) -> bool: + return callable(getattr(value, "__html__", None)) + + def to_json(self, value: t.Any) -> t.Any: + return str(value.__html__()) + + def to_python(self, value: t.Any) -> t.Any: + return Markup(value) + + +class TagUUID(JSONTag): + __slots__ = () + key = " u" + + def check(self, value: t.Any) -> bool: + return isinstance(value, UUID) + + def to_json(self, value: t.Any) -> t.Any: + return value.hex + + def to_python(self, value: t.Any) -> t.Any: + return UUID(value) + + +class TagDateTime(JSONTag): + __slots__ = () + key = " d" + + def check(self, value: t.Any) -> bool: + return isinstance(value, datetime) + + def to_json(self, value: t.Any) -> t.Any: + return http_date(value) + + def to_python(self, value: t.Any) -> t.Any: + return parse_date(value) + + +class TaggedJSONSerializer: + """Serializer that uses a tag system to compactly represent objects that + are not JSON types. Passed as the intermediate serializer to + :class:`itsdangerous.Serializer`. + + The following extra types are supported: + + * :class:`dict` + * :class:`tuple` + * :class:`bytes` + * :class:`~markupsafe.Markup` + * :class:`~uuid.UUID` + * :class:`~datetime.datetime` + """ + + __slots__ = ("tags", "order") + + #: Tag classes to bind when creating the serializer. Other tags can be + #: added later using :meth:`~register`. + default_tags = [ + TagDict, + PassDict, + TagTuple, + PassList, + TagBytes, + TagMarkup, + TagUUID, + TagDateTime, + ] + + def __init__(self) -> None: + self.tags: dict[str, JSONTag] = {} + self.order: list[JSONTag] = [] + + for cls in self.default_tags: + self.register(cls) + + def register( + self, + tag_class: type[JSONTag], + force: bool = False, + index: int | None = None, + ) -> None: + """Register a new tag with this serializer. + + :param tag_class: tag class to register. Will be instantiated with this + serializer instance. + :param force: overwrite an existing tag. If false (default), a + :exc:`KeyError` is raised. + :param index: index to insert the new tag in the tag order. Useful when + the new tag is a special case of an existing tag. If ``None`` + (default), the tag is appended to the end of the order. + + :raise KeyError: if the tag key is already registered and ``force`` is + not true. + """ + tag = tag_class(self) + key = tag.key + + if key is not None: + if not force and key in self.tags: + raise KeyError(f"Tag '{key}' is already registered.") + + self.tags[key] = tag + + if index is None: + self.order.append(tag) + else: + self.order.insert(index, tag) + + def tag(self, value: t.Any) -> dict[str, t.Any]: + """Convert a value to a tagged representation if necessary.""" + for tag in self.order: + if tag.check(value): + return tag.tag(value) + + return value + + def untag(self, value: dict[str, t.Any]) -> t.Any: + """Convert a tagged representation back to the original type.""" + if len(value) != 1: + return value + + key = next(iter(value)) + + if key not in self.tags: + return value + + return self.tags[key].to_python(value[key]) + + def dumps(self, value: t.Any) -> str: + """Tag the value and dump it to a compact JSON string.""" + return dumps(self.tag(value), separators=(",", ":")) + + def loads(self, value: str) -> t.Any: + """Load data from a JSON string and deserialized any tagged objects.""" + return loads(value, object_hook=self.untag) diff --git a/env/lib/python3.10/site-packages/flask/logging.py b/env/lib/python3.10/site-packages/flask/logging.py new file mode 100644 index 0000000..b452f71 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/logging.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +import logging +import sys +import typing as t + +from werkzeug.local import LocalProxy + +from .globals import request + +if t.TYPE_CHECKING: # pragma: no cover + from .sansio.app import App + + +@LocalProxy +def wsgi_errors_stream() -> t.TextIO: + """Find the most appropriate error stream for the application. If a request + is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``. + + If you configure your own :class:`logging.StreamHandler`, you may want to + use this for the stream. If you are using file or dict configuration and + can't import this directly, you can refer to it as + ``ext://flask.logging.wsgi_errors_stream``. + """ + return request.environ["wsgi.errors"] if request else sys.stderr + + +def has_level_handler(logger: logging.Logger) -> bool: + """Check if there is a handler in the logging chain that will handle the + given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`. + """ + level = logger.getEffectiveLevel() + current = logger + + while current: + if any(handler.level <= level for handler in current.handlers): + return True + + if not current.propagate: + break + + current = current.parent # type: ignore + + return False + + +#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format +#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``. +default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore +default_handler.setFormatter( + logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s") +) + + +def create_logger(app: App) -> logging.Logger: + """Get the Flask app's logger and configure it if needed. + + The logger name will be the same as + :attr:`app.import_name `. + + When :attr:`~flask.Flask.debug` is enabled, set the logger level to + :data:`logging.DEBUG` if it is not set. + + If there is no handler for the logger's effective level, add a + :class:`~logging.StreamHandler` for + :func:`~flask.logging.wsgi_errors_stream` with a basic format. + """ + logger = logging.getLogger(app.name) + + if app.debug and not logger.level: + logger.setLevel(logging.DEBUG) + + if not has_level_handler(logger): + logger.addHandler(default_handler) + + return logger diff --git a/env/lib/python3.10/site-packages/flask/py.typed b/env/lib/python3.10/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/flask/sansio/README.md b/env/lib/python3.10/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/sansio/README.md @@ -0,0 +1,6 @@ +# Sansio + +This folder contains code that can be used by alternative Flask +implementations, for example Quart. The code therefore cannot do any +IO, nor be part of a likely IO path. Finally this code cannot use the +Flask globals. diff --git a/env/lib/python3.10/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62ed297799f57d4f44071214f26a6056f964f3d1 GIT binary patch literal 28551 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc b/env/lib/python3.10/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..288e9355553a780489b10ebfa2a43994bc0fac72 GIT binary patch literal 22773 zcmd^nYj7M_c3yYS1A_rD1V8|MiracZSV2Q_wbmvGO)o`CT6wjwOhVdS$lSqTx&aJ0 zm;t*7BrzGTvrBq~Do2jvbz;YB#h_ma^RTmVD%qr**ol)=ocu|p%2lcU<8p1PlC6}h zQl%t6D6g3BJGc9G_h2A$Wv$Cq85Hi^d;31mIrqHo>1mCO6b*d-=((SC?|;cKzRg1N zlSSdvhGF_|n1|#1zA?Cw zSu7$y;1n7|8^epkk{?8VWN}3DMdVA1CCLvVe_-)|X}H<-QSTgj4L8O%#uvw>=AbjO zYU0Vk73+wxIDy=xQ*w*zQ_g|6t;Iu99!2@El#fVx4CSLzJ|^XHl#fgK5h));`Gk}| zCgll~Z7Dx0!GKwOwyD{dtxhccr@3Xgl><8^zMrrc-UZ zmFr%0bJO*{W2s*G_V#AIx%wR-h=UxixJ_rXRd2Q{D_(1(a;@%OudHk}Yj`$T@!e*- z-gFx%6fV`OD=V#rgZz;1wzoDn-1b_F#mu?Q&EVh*jV*W6!$6n#@Ddj01_u@@)s?pE zRXq3Vmg{p_x#iYY(+NfwD$DLl%X6bgZ0mYn%d4zan@+>^g5pA@?N&Xfb-fuJXMSU| z!41_~&9-}^UD@9do!c^62qqSUZZ~{F>8;c1_3zaReQ3=832ZvSp zS`|CN=-5p-L5&bkel(qb9JQ{oXgUUH+g!{zhn!*HFT0o>EDe^N!@%aGGj%(+m~%?N z-BE7@9Xfx!fW5T5s<&;g0iv#Fx0cu4TH6LdY|mY-``7}IWLNFw2&(q=dV9@ouen7V zAE2~RuLvaguQ2PVpP|WHMCoHwb9V)wQDFXS8G>nl8;bjS=t4I zdK1B*o-D{<58g1q5e&38rTM*FyL_&>9gMHkJ--dYARs*1WRP8MwHiU*!{WSVkezQe z-C8bzk^$uN_&-nX^XtfTt*%iqx+YSyn?Y)Ivq+I!w|29RdB?n&>*gF|%kYk(&Roy2 zj28Hp78Y9MyLoBxjI_wJj28Hp7MZTOK5&Qg41_gVCnx1Xdr*25Z*l%1&>7@dIaUI)NcgYW_802hL}cGMlhTt*t^Eeh<6No^^Pz( z&g2A=AhYVWy~kL5oXHbRp5%ipc|&lJg9w%Tn)tnGKF=$jF*6WkeYdfq#+4cL;E8dc z=D1Amt(;tIZMY|wt6m4xeDXD~MRN8}zH#aN$0&OXX;o`5^0UHQXQrItvOBC%jig(eBzL zvS3hi#Cv1y@_EpBb-Ce&PitfZ(TC(mGW;w_@HdbF!XW~;Oz%k7^rjqZ7sRk`>{<@c z-!*qL{9YlMnN55ef`)Tq5bzlLDZB!FL`pnPBktd5nUvR4)PPKrV2+U+o z)vY!tzYSK#u@vQlSEYCz2h(IQ?b|#NinH*^{5|ue&}2~1jNB~Gl!Wwy>^ejn*ai?< z-wg5%^<4yy3mYqPE&y9{0z5MGAhX%pl!FxvR~<)$1otjyNKVsC-g}l^PBHlelTR{{ zL-Hx+^wIFjES^R3dHnlNAt?@J%@bzcDuG}@viP4u$uf_dmYMyom9_rF$`#-1*!>7M zxty7zI-f^5gB((FQ?-akm?JOnKE}jm@+guSYknU6WZkD(DT{xOIoZJvFelrP5o{Kv zU!G@Acu^%NRw^4U2LP#5g5gT#>Q=Q8J{hP~oK~$;@lLWMcb$NQz(l}7AxQS*bHN28 zYZmj?Y0Dh_lN!pY4-tcp>3h&uQi9fk5}8TF!b zz%4kAbIdt@JA2Dq9F)={&Iu_M2Q9~SR-C7tX^80|JX>`>?mQ#UhMhHM)_E2qj5u|t z?3_fdW>h@WCIdZKw@R zd)d`|1`RMy73FFp$vk8j(Lu^Z$)AfCA)Ex0DP_OFXKlUqad&|c@BaO@lSHg5PsCDg@hyDBZoakU$ z&w7d4*3zuKjLEPr7mdgun=WAj#jo0oKozNW)Y&`^>2M2Zyde#hCYDr>LXccg(<{v} z(!vxoO`t5)2#H2nhL^yJtUv%r%@IJvGhxO(d(r&ZkJZOmzAh=iuDMOwp>9k(Me-!X za|+bqHZHlYJqJEAx0De7OS1J1SPam00WM07Rx|7|w^{Y78zLFz>;(dq*br6Njme~J zf4&Zd6~sp69%2Yyek1 zA_ls&RK_9!3kqA`ZnU7ty8@}DC9lp#VwAoZkA?=nNuV3#riX~oogkCA6EOfz1#V93 zQ-c$0fZPD*_T#106}wRgiAPXSN7#|P>8QBMd0@9E# zaE~EmeGX33kIM<`Y-IrUpGl)eW+c#g*1;hnR3#_UENjkwLAOw6Bi?}wl-Bm4gzI_4 zWwBg^Yk@mkT1qfmIiO9u=6Y?I$Tn=nEn)p6@4Bx?&|_nb?NA$`YOzwSH)d^L86$$} zP~q@5-CBL6o;VR3)uym)ai&1nhr*>?wy!~0L)z3pbE~d1H)o$NpDv%$bH5NF3M^fb z>(WxKQ3nfO1?DzMP?6Y!xQBDcvCqHy3iPH8OzHSBpW=a&t`+Hs0YtE2LmpZ;+g_`| zZKvg%ngdR?P}d?8Wt*iXv7|9bIMJT{2t&YbPL)3;dwFSI`3h(m1VafN1S2V)dGD|? zkXwHFHSpqB>o^3VxqKjOC?^chJlYn)f#@`bVoLcX9>XKCy6z1LaYh!mCa7Q#P*k9( z4WV)LVV;(DhL%ACnYM8YE*!XgGH~+bx`U4Sb`JKl>5sKxZQnA#YQm~EVKpB?88*OI zVSmFhlM#1LwhQ-7CASKD9j={%a`@DZn}u!xH3Quu(tQrsgmW&af>K1Z*76zV>$6`wM*hOwVItm1GTF4B}?GJZ*!>ylM>?FV7T% zoWBKgT+FGU_y!%5FVaV<(DXPbB@lygoJ%xw9dX@?GtGO3Pk)$ChbsCU`ZGhyauuIY zzfI^tl|9To$tZW}53Yzt3;Qm%i>5 zMYA)mkBs)k1o;(Fu3}@gW?{(a!#q7KShMMK)9`E<-hsC10GIG^&^rPjhm&~+_89O@ zOl9Xg<2+K}G&qH!FLSyx3m}6tG+U4=IL{tMZK&&l`S9pyc-hmP|2!?q{u&heY6Dh@ zvyJx9Y@-v6!wg>CaI56@6!cK!w~0jz?JHG)ngqo;jS4ge&V9Ogo9)JSx%fGX5Pu7@ zkwQluI)4^iEHWi#V}oVZcH6bGm<$*PYy~^B$zW1z7C8&w73QReU9XgOLA_m`$pjOX zRj8Tq4k}!DP&x#HV<+1l{AVz#;C~bu;vXJ0IC4Y(mDTy9i=pqFwvD!b zdd-=BW{GCyF-$0k2v@Xp zu18Tc8w-ee;Nx@He2~YoV5>yvc^!4V=z+7GrsE&tk1*|2=}ALUJ^@}*H21j#ZUvg z!;y%51C&?#nIKD)1-B`Of+)~W0q<55jzWD}Yp}#a^W=sDGm2aO&cV>NS(5O8QBTJCicoQt<>(T91${~*CSg^X~n!5w_xBJF}x@&B%g zOFZ$}-8H>0q8Ywow90`S2=DU#7oPfLhIwk%i$0R+0 zDJMFIBMr(iCl_f0Oc2%(?YFX^H?#BY^KzkugO$GZN?&SeBKQCY1qm~EjFsMI%6m*d?;b8dEXXy+6Ub0i!Zk#p zjcWo?ouF#%TEq!2FF?S&mCjWE5Of~#U+lBTVWgL_q)r~7qES?~KkIH^2dmPDFXEX# z^k3dL5`qHBP=*VGNWhq$H*p!jXOXZfdZl@&025#Rl=@GUPnA#WHL%qJ(7&`qg$`P@ zy7UnALYTw(C(BZTUI^uB7?96Gje~w4UxRQM@kWu9^p<-(Vf596J|QRpbX>AEU5csY z#N7c8tRbRItYicJlKLj@XUN>BcEC@w)vV*zU1pE%B(8_vM&-&t4)&FDsPah+mdG{$ zQ1lu)Po9^U13fYD9Ipw`uD5w@I1euJDhS7$XTp1rh^@r;lsz;&9&II7RqvypFu6jh zU``}2^2&P~*D`1wea4U};2(9S|244QuC)u=#dVu?Gb8!T4rmyqY&Qdy5f^H>9LwNh z4%cXM3v8}uU@V-&{cfh4J7VmR{-1PmP1E5WFieaq8Sk_+(9NND;hhZXt(ybwtTV`w zoMJbRbf`OkboiYCo|$$|B zjve!DyDOkkgPumY5K$5lN~c=K3yxP1`M zzS+&O7B}i>vpd1OJRj=HD82P~K8d-%@?+M`k(;G%X?N<5A>W2G2}mD6jp0loH`*PQ zx&Lc-Wc?6I#q~odo8JGFdi9+>WUwA-$(cH1G!KT){&#mYtSRb#?=z=ry9YS(Pn%vI zV;{zxjP=3TsCiVLsT^u|k2r_!m=0$+09rs^=9@ju)eWLtaYP@;n;L&@b-gq50AI$R_3_h_ZwqsWxyg#~o|KZaj>0%;0C=wD0CLEz! zgohG5k!aA1JME0dN6Z+I(hR0*btqM%p2gA2_V+;SE2z`YC+g4!>j7(5&CHkp? zEY+>f5ZqD`RyvkFeb1ck6bT>EXr?>Ir>V$9Zjl7;sbO@AF(Nx~qP*_Aws^mOaGIPA z(RJ6TAy<=nO1YM_oM<&su)~LF`iGJE3XFlv1BjC`DU#nXz*;TZPTnFOim5VV1y=b~ zU@dRLe0nyjRkq9EnN_#x-q`fcp1~|)xmbT?%IG}#Lgc^ITsXF!bf1OJ=*cs5AkXoZ zh5$Glp=2AI`#hL+FH!GnS z2u6^PFM5Ju6!is*GHX}3E80+=k7SHQ(LrYTkrEWnqBUh6HZAxs5teh`5;xX~d=d3| zvjjgTqE_JCLj89O1H-5-nk9?g&It+Y8HKmA#2U0JBA++MEk0pMjWJ~%whH%)nIdd> zwkVm||CaQNMsQB4wp43r_={@$Uyu>C66)ve0#sY^h*7b;{1{ZOEL2$pT0?D{+%cN@ z9Rms@{Nq%0Z)V$88!=!`?zYj*?V6!7YK6)#V#>}KR~fdLRnIODV!Zs#0eH&I^=vnf zr_V8{a-E86?iOR!SjwZ6*Cn2=}uWf!lWslMp<-fR37*a$( zlx*@a79|?JY_g;`34K{MDK_d6Iteq>Qm+CS(88>F@x+5sJHM8$`PR0DB|8b1Di<(*% zl;V8kdc^Z3az0LqI6vcZ2^(e{AiUd-3CzK)QJDL>b(KcAwPy?hPR5|$NyZq6#^_qA zm)g$Lcn&Mg!B;To-l!>0f5HL928xXq&k!u&6q{$ihP}T_E)6dFLl3{}cz|-8h0o*5 ziA8|x;Q)%>H`&hksC4c zdqa%91R&8}N` zeiYBuO`x%xdCPdqe9L+(^Hz2x$5&8p7sxOiI=BnfQNZP5sCC;_#sH{DSgo3BQC_ws zbcs%?xuvo)C@58lO$LxkNRQTBSGI89gD@w#9Y{tqQ8A;ErDuYU1=kXS!l6U&omIsp zge_EN4}>bTmuq0Q!wRX2AeAX@SJucHOn3xx-+F-`w& zPMrh^bmc=urJ}>de6Db&QQcT}s%L+b2V)$~vWB|ajG}b&?{%Jz*-aADF^7)^nTIo% zPO)GB8eO&B_5>K>dEY0RSQaKrlr{Yv*C~gU`}kX2Qwf>j0|gU`gqgL*&BFc8RR8td z`$T-L_U4<37h#~w;`ZY5ti87`C56caDNOKfzB_@8Gr&W$0-qU_2;L4+02QhO>BADS zD@LGU9^8#yLp+9@dtQ3uqExqlz(oXu@{GW0)W;;@B`Di3B1RLej7B0%h|qKoPg*om zMa`9TYlaR2((s(PR-*uRMSr0yK3bz(O`T7ylCXBnb&&85r25;`r698JLQNri#v4Nc9eLBvlB*z3cuK zNtf#x9m-}qk0c0oZ(Eu9-Vq3mh4A&SmxPca>5)>7IVS&wMo%Ea`%9rwb%O~Nbr*`N zX6=L3SH8d0nz$JSB}L@g2P8}Jb$<_y>tm3nb&|xNH+t`Px44Jw$wv;7htQno73exV z@$1%(xe4F*dIo-P5Wkr7AUocB1%vDL=6V&cDP9W(6yf`db-szGAbz1uA;6e*k446l z2GSq!5KvP+Y?Lta~7boZg3URsTO59;xQ~=(%LHhmVv`P7;?kl0B41 zEsRn=#V7abv1(QOa>^0NYsD!O9<>xtQv<}Lx0hGyHF}cUmsh40RW&Z7w!GiMR`yj= zRlAga`m+4kz(aG(`uCUU9)e%0J^bl7W;n)2&NJ1xv-U?twjTl498ha|0N;F+q$7Ou zgOp7*R7}3#Gw1vk&l#usr=-#k(kj(d9s_4nj1Zl5%;&pQCuk$ZmkP9%cA$~ZWIFFi zn15)7q&=VEOO0W;v5VL@zPBiT&RL0?l%P#{SqCpj@Yg-!P_N$C&U);h$Y=^}{GNGZ zV|!l~6mE)U27)?_RpXAe3rEo%Gi_#gKZ(72XP7Wx$@?2jcA3Ni@#j&TCA7bWOj3Ib zS4GwoZacs?V3|U+weh{9JcY^LEnu>24tGuWvzf%N8I<=n_eyBG zFLu4(##7+&7m|2P`Km)SN}c`v#A15Zhd`qDFR}KN2J=^0@nCd4uhI2vLVuB;qdeAhc7N6*SigWxfnx+)$-Z?z_c^-(I-6V2)?+hLuKiX>$p0+67d|6*~Kfsfw zes(9KX6Pf4=WE|{wiiWj6M7Fu(Wfj4oJpt!^&QxD4P4pXJP9y3>Obq=RdeB`S zjH_Qu;%d)zOo%K7LPRDIgS28Fr#fJCg$s|=5Efqfy>Z38lYc0L{q(~j>{X4h(=ix{ zr#;K~UNAP*Z($erCh;p*?wc>(sJZgfLYHxSgkPrWb*iMU z{KRNT*QAasJy(%;F?6bQ{$`Q{q^~+~yiwt6{>1)6G1BDAoOBgF;#ebbYALVXaB^uPO%WtR z)Tp(kh3Xf9Wgq{>XzCi76p-RSFh^rJq5@5t6 zkYYx{{qH3Svi~LW!;+?ENFPpy>@#^xq#01>5|J)dSw{nxS| z?evrSM~RO9!+eRe{#&fD^Tfl<>K#JU2jVfsSU7L=e#66JFVeF=Bx6ZU`Jr(3QxAu; zO^vhJz0iv`{k>pHPFQmJ>zv_tiJzX+m25OK;XT0xpJsAi=Poe!B9oVxJjdi^UH7=I zdrar1nfnYAd2?2JFd|U;!u|H6%*!k`bB`iH?d#0H!Ng`FwdP9*=->^A{79bqQKp`^ zr=;-+n&1XmUajC&c>kYo>N}G3m&x*p=P@AS=b3r@Zq)GpzZ>;4ocQZZewN8`CVaCf z-cO{x%jg0Yo6mm%30D7$%>O!*p64NedTResqSrrp=wAOU(d%FA-%Hj)0jCzv98e^+ zG_X`Hb5SiddsWL^RC`d@GKX3b3ja>m{`*8*@^&=>bI}Oo6snfFnG@>T>(i_~$K(Yj z7nv}CQ~l=F0&_!5zQBZ+RNfMkDifbclgU{ozs7{OQ{F#j@=YfHoXNMC{0@_U&E(%O z`8_7T&*VQc`AW8 z+A0p4RssK|;rrGgA|l6%>(&V?%NC{gkh4nntOeE$I6$euV7HF`4N2N%gd48Q_^Ln9TfcV$56cj zsucK(%n|az$if$2d$Dr?`vx$0sW&L~g-g@qySjp|2Lbu&_LFcmdRU%yKvK>YCKl=f@>Ii1hyX{gSSq-dboXf^~n4Y zNsqLTt{$5|Ch5`k@zuxXA9D)9<^Ny{5K?j82Ks5KO^}g$k!x4E%~F! zpOgHvYFa&}9=}tXf9{QfdP1GJQ&1;vyYtVhbLx~jjrT98XVqCXiPVegY4wdeh527m zlr4R2mj?$yHN^MA#inskz3ztic)e%$JIqFLruu;};Nv1&DAWXF1I%8!HkjnH3P z3qrgZztn06SJ$IBSbeMOD|t6zD%FFV&0tO1LdnrL=jN_lOyA(ezNX(?4pezSr6uRx`fI)|x>S zb;HEDR70_Wg>J8-l6`Y^e=!cidKi4#3!*p~pQ|qfi`_7=Z%`x%!){n#_B*N_gh_R- z9tVD?x;Hw><4mXBbUSfy69chbjm_12VLKgAlpNLh>wdczpjgl^IXH(&^x`0K7L#%q z#J#Z71U}dwu0a{UMPkZXB<>bg3O{hv;OB+Uokdp-sPdhWTTblUbK_!M+H~#~ZoBun zhn3l+HM+t zZlP7!bpO=(p>wtHg+ov{RL5>Luhka-&4-efT;ML~NpJdTFK$MN{W4Ugha zQeLcg{MF!#!j_s|?yd&Y3x2o(0GYlLc2|OC98JG}^}_TA!NOIvyBf@OmzLVWbkMmz z-EJ*RudT<+-Ols1XU|PXtvGmQ&2L`wmx5?|vF%6KrX#--wYt+$(_dWdwpDFyJsB}T zSzqjRnonZ{5hq!74m%r9%9vLJG^uJYx4TWh9lcu1mY*!^2|R`>GK)}BTsuik4kVSj z%%@&YoH!{p{U{E{_?f*->N$r`@x>`VJU&k2kql=#KZ6$$x3}z!yA!358{EWi?#B|! zKL=n0g?UF6=H2%|FhL^Sprnc~7gP!4aRBMEq|1^Xe7P`G(*KmN7Sx#9cV}RJP&L(l zH33wwD5Vam!$=JURTZcs>gb))ZD)Qs7+x7si|V+|SJjewTstLhc?>YV}fc?@Mb>Ral(lsS%ESG}$-O71b_*3=v7P02lu z+^6c>>N}Eq0=ZEAx|)^T3FIPmMZF`rlgP#Ds+yCWhg?tnhWb!)Pa=0+eWX5?+^OKS zx}oZ-A-Shi35a+zsa!R1>HlBg^M&r}YPaJp1k3*QRyXvbWj_oQ^6`xz=y)?tKy)=*4)o+Eu-F;N4gb!T>K?k=I=yPD(rM7H>dZTb)4Fy!WD>-)^saGkzS0GmR7t z8kk78*XBgLUW9_#K}6&s%{p;22xq)2AlY8r^?Xmi;W%^=ZxQ?>;uQ`34;!1j#9NaEtbAZ>S_DQKJ7mu``P#AL{>X_I6){b8DP`~q3x zA0n~oY!>QZfOtBaMLgZj5}w6PNTt0(cnF*qeEGI>YhZH#?+4=YZLrSzAed&MUWtd4 zque|Aj$Ab!iiagNVpF3wHO7=G#QT<*|C^^IrsZdENLW{2D z5Ry`1*D1?vw=ZkDaBrYiRKufOExTo>JWz3~PPtSmmn+qY(of3!OFu1-;}?I&nC82Q z%1<};@7RK!G8{!l$_WCn6up!a1N3e?E6yK5odR&Wf8?s-j|KoXrP(d#Bi*Ht6R@Ubevy%hiGZ<6icB7=kj*`+!x7E=|bO~R!F9k8~ zFYzlfWOZP|DY+Ym?Q-PEWHKNizGGX8s4h^$9p8j(iM1Gs3-=)P--lA6@VtdI2vJdp zjyt>Iemp%{3g1F`2=$SSvmAm5x7K9%5cp;9-bR7l2K>M9UItuo$DOL1loq<(_Ksa5 z$jG>8MM!r^_T!yKV=nAraXl=m5khiP#Rm}*j2uMiVJA~MS9{TJ4%8V5@BiThIKFCmrTW$A&uK;a*` z_Xd=E9{?#pS={(D0%b;$5jlWN*#P1;si;XExU~QoZ!zqyW)=ow6`1`EKN9Aj0ch2u zwBnKGPqBzdfFWcCB~941+jRpnFumnWLzyDk(@RXS34a}rq(Y&B!a(>AvMI*D&+mjq z{W#4OdCC@kBeIn0U>Q&|=8O~AkJ{xo5RkI^z2TfXse$vMP3ImK)IvC*pAa@1zK1dx z5XYs5{w`Cyj0&cw6qc(P)z*>i<_{x^>LX61#42GEeT9mTZQE5^>qhaj7<{;huN$Lw z=zRacu|LutTzT&ihh9XDy+>YL>&3rn2i{+Eynf)g>yNVLuU~xY;@rhY1D~?4wD;)C zDrg6BaNbT}pIv$V<$-hf?xW1%%K5nqZ$8=-2Bgm3GZ=tG)?B`9CopCwARlt$PpKI+ zG$%R?K+}fh&)vnMDyadOmW!Lj>WcrrfkUrrA_ZyKqaNp_IuU7B7%V|!3qlbmh~=bi zOOO{j6jLnsAoUgNgdxB+kCZp^44Ht*KrH7h)|i4ps?}WfAX&je6$Z8u6~N?zN9()xqAD)Q{7*;Tg`<&cw(^ zVym;YISfmna}|s*Ap>YM`lK7h-@JJKb(Bqwl$=hZ@%ELu%WuzK<$IW%#2DoHy|}wd zQy}e4nQfZUwn}chHf~Y065U+~ zwh{D}WXIX`yM#3(LG}9)r$u;#lzE58gzSWvbAVX$btLWz4^$A>ZaH_|73Z#KOpC=9 zzL5Jn;F2O)CY5wAz{rbh-L+&S3-XXT=_?7lc!0YJ8yD^-{9QQ2X?#kCthlfOG#6!R z1da_T!%tdd7pUnQYix~Khzrt*otvH|TTdm4K1Yo>9O*b@ioJ(*JlYrGbq; ziIHAq{K=5D^=utkjBD@G&6SE-sfF$sJYm;cDyUn)sGF_a8m3y9iqDid(w{OC=v^d` z@G=sUj{j@0cfFfZAYVg{m|fASR%4poRVIwP53~ao(uH2Dt?xGf^Nfw%Em^ z8syW^tpyyw86g?K){1N+BI9VpvnwD-U_>~!4*`!z0pDW_YB>bEnLgEk#QgIkS+!aQ z>mH`3uOxuE)`(@Kq*;I_L7ft2A?CPOgp^M9=laV-A-(e*PwbSLebz3A&~MQ=4r&W` zhOrU~&+^-0;H!1GCBOtz{z&~ws7~Me?*)y9lyG znvl(Mc32iANvpjDt4(Hx*=S@TTy^2Op$`GpKbRZ*utlFjfUbcj@XcsmGX=DRIYD@n z?Mst-?LPu50E1{jSOH(h!Wk6yvHm&sxY~9_4-bv<7 zh5QJ#0fF8_4jEACe)R#Hf#_QT-W27vLUU0uq;H%fEE3+Jb%p7eY zJ@niNh^Lhh=Z?X3{P1OxHXYAE?t6I>Cz`T z6|9J6C`jS2^W%d^*w`MefVrCz&Ex-bboHF6cV0*qZvy6Y^<1sRp(2CBw zHBUo%g6shdoyZ51?mW{lUQth6k=&L*C#hEHC`)1dm>AliQwk;Qniy+~)a|c5 z@lXr1i@gxV8EPXDow`9${`%vH;w}PJ5g=q+oijm2{&kp?=m9{Ki?`5)0Sj`R))Lde zDq|zSBtIZS$9gg(24z@O1DS0$xEa6#4tY3*QpCipr$gJ`fM>(F45)6a-ETG93Kj<< zE!WUiH;YIeHe-onLRBb3Ze7Qh)Ds7fQ6JQSni&mM)K>HdwJHt5=4c6| zt2&^~jB^6%>)@XQ^ zwK70CV5)G^GU%W2|ac<`8>^ zZN{_=hlNkWkGIxiR6KGW9W)DAz5#E6XTmGMA!wh>AnC(M4w|6D)W+&539g&2cas!y zBCjwnu12H5hJelD903_<#gTUw2-9fb) zoAyg-i=8$W2|9ZEDs9snbDb(0*w9JL}*KLO>Pp27KQ;pTu(lY$<5OFw? zb=_dp!_;sXMi-I78nSFdjYb@=0eQyf=3Q6);Q|NKqj3JUgu|)bLi1aZlfNd`q z(q^$k1cSt-bv%C6@lD4}P@&cDPD2??X*cbYX-E-OF$U=(O5dE_vZybz1<<`OfAlp$ z3x77&KGUXD^sWW4h7%Yqgn~9RAUb2^1ckm1(=}CrK6mJA2hg)vI~{8d>_I6h!ToGC z2}^!OmPsW7o+iN9?J%~fBz;yGkM%rO{&GjHX4#2g(esQh}&4Dp?OuDr~zX z4LF4bRoc^oO~<&WcmXxS?0EkOT~48J!&eEwdrBAkcT_(K&=QNt_!xk+eWMh z?yAgWhC<)WcD#e%pgXYARx;;XdGDs!3IRx{fC<#;nd1Q=z>uWZP%zroj>*H zXl)5i0ZMA#B{0;lG`v8r@O;}A{IWa^)%H6}Jsjv0*QZ%rLXuW-sLpgCmMnn*A#{RT zK9t{%xFX2dGwOkcIT=cxBc=bzfEw4t9}niU~g&{Sia=B9TZt^C4xmqp$j z2@rYefvhW6*RHyu@zgW_<~9U_=C;w4Hp#%g3fmc^E32403%d>F|ISyU{Ndf(IA`(x zF!27QWm>zJ4i7yH@{06H(=$Y~zONe7IDBg!GYEtYZ{yGA*r_b$gEu11m-(JKd$ z8DL~mYtObNee_yLwSiaz)xZ?Nnj8Tjxc-7z(=Rt%ru(@K8o%|G&^SW)N^4%WFgOet z?1v*~%Oqe~h5xnTGoHG?MS)=DU1A_9#Y@iw-l~p z3JB!8ySK({v=}YW)8j8XfzWeva9_ubXCUi*-%YM*37||2JFuXoiV`@cCB8Z$Fr#Hj zXVOv4LokL>duPNB#5$f0 zT!0E3#b>5GG~Z_)A9j1fG;v5gGbf`F8oUn|S_ngfh1YIp^x#RnZd?x+IkTP9;W@aL z-|j<5y2lTkS=ulKY2(un-7ip>+l%MU_2>3;vW3yrk_RRcD{>6tft;(~h^2W3GNrM< zH4C$?lDOt1R@3xXu`n5lfdP;T+ZN0>u-Ro#zn-hTWWN%aGv>+^LGt%Zz{t=+BrSYS z&{VXfmW@$k8|Dm#3?hXJIX8)@6~uQmt~qlR!a9y*pp4I$jFx1f)! zXw5A<`khgowzH^~yI`cTgLE0!?+!vdBRo||A9O*G;9!Z)K9E6jXR};6A0fA7_aCg0 zzmqoD8E7Zz1bNGjAX7*k{UB4iIqo{RmIJ!Sa47ndEx!^+ko7NQht@ya*^dqta0Ultv^q}W z!Bz*e8z2WauRvGV2YU!eaEA8zriF%H1ZMQmXgG@q;v;q5f&-AR3xd?KMo^_;8u(Q# z0#1|mcY_|cWXP7pg(WN|5Frl%i{C||+v%>1jo_w~z68BHkR|(VlN4sy=+-IR2ZMuD z+oT!TN)gwt5Bz`9Byguc=nyB(&F&Facybvh*WK{(jdF~=J65>md{F32lnQZi9Tzb1 zUtGeOqXN%1|EPG|QN_>P8>oegaIo+30O~#+mvL~?Riz)vsjPTVzmL8tHJz0T>JG5( zXO4UuLY>!eipg22E+XItCj^W9J6ZOJG1xZ(WB*U3Gjo7$A)qZ*(*!sVsQZ%Y$SKSo zM0>19pWfjkLgll!9zmT=iCYj&L0}T2sd%476R^EuV=b8Qq@!s&11xDEi-iTV9Ww}A z&4?v>+@xMKe`m&On)z zpj~r$`kkA;#1&~CAUztsSDW2f7Hx&SW44_p9ErL!0rQ$?h=Gpj=yn*MO6QI~fkGn& zrgzaUo>YP>KHZ%D2&39YJ2RDZFUWXp^`B*Llfy}s=6gM~08P1+mz7wopB$-R9 z@AHx3=Mx26PJK#8|mLfVje*%DVXC8WO{B|cz@O86n$ zkWosEpQI$RkEcL&&mXg7S)Zcpe}63hy~s(AWC}^7lyn`lWRDMt8^pzTCU~&lgbcl; zgSn&&8SYJ#Oj+xG){?hOrEe(%=(kLzZ|Nn~Z<$Kp((10?GL^oity8~cDt${Mh=BkEd<1+f^RdE5n~x43bv{1jL-z2unEH&5+kE^zK7N~z&-wU0KFB1K5q;cTN4ti^ zung7-{s}{!#D{0`8`1YtEtH(fenGwg7YGPc+bVpodZ=1-i$J;|AY~c9gGlew>FS6( ztl#i$?)M~67cGqaKlcK@9Kr8#{2s*bllUFS?@|1Y;`bZ)9UFH-jzuC`x2k=Mf?z|A z8-v*uKrFN@MKIZfwA90eGT-i>Z{}I1;zo2CqA{eWwznL#u_Kz0YaXTpSd2xaZ(}80 z_VuYi;Ww$61=U|PQFC4ayoKy9{VJwe&46Y%rh}W%iy7ok8?TgMP`EYY8op%0mKCo2 z6BxuFK~32kyFtm(dRnngrLxX8<)q5L#TsY_LaFS8f5Nrnr3G8#yzT-Q($%iOT7Cs- zTwj6c!H_g)hZ}*Ac!4r0&xmc{q6aONI)x8J0);%|tWRip=0mLR)xr&4>N9r}LqSMUL~oA)(K6Lv}9Sa&Eb|+znhxu)>>BcuxXOgDMvn9vy)cC9)IbvVEAxKwMgM z*UuQ)tbA|qK5i}i5O4yithiE9C7h7|IK5#7?UXi4XvYcP*(|LLh3~}Gd&6;gW#rx{ z^Y_uy4+`sX<7ExMm4;_H7REVhp|wSM(e69zC)Q>bv1Z4v7FKIGU>UEVp7hWm1Nu=#H7TvFk+gw(5X zL(Yg9jcl{t{L?6z486P*bbt@xtN)Xm%}`$V`z366#c_WE4*%uG*LX1_uGG}GB})Ci zPG@U}MEc3`WJr$Qu+wBnU$_NGPf9pK*G`6{A=;z_9Ft*O*@IJXBB+?VV0fthhDyra zu(j0cB*!7E7_uM1`QKc|g$;U2Q8H-IC@B$#1hSK=b_MYZE(wGGHyMO6gX;_KGtK#q z%57a}Q_eypPTkz!B{xRdMUvdUZC&bB`=@9{G~i@n=feCau3-%&#$DGPf&4>>Xxtqs zyIa-Dh&u*~OWA0oSaPdBtqzXh4yVKJSTX!}Y?R~6LBJqh5CR1M{}>5<9}}>e^gh_s#-R5sB66;1EIFtWBD0_BbRvY~pTz=vuRvW+J(-);pWtWwRdD^tc+6 zq9}pYgfWB`Tt@1hZ8UNhkTx2VQ_@Hy4Q|F7sQ4oNfVk}$wJw=Y5vn}`a+0I_x9H7d7u z#We@s7|l&TDPrMgCr33FyahPd$UKM(vjmfiSlpznms7Y;_^(hXsaXCw5Wx)|Cj$t3 zg&6lfTlm*_Ob%+L;-9hf(Aqj(g}Aa2*Qet8R}eCe(PZ?kOz1?vEbIJsCOML&gnvz3 zKaQp=qqs?^Si$wHBgJuN1gV4gTPaqG;eX^%HaV1%mK})2T2Q9g4x%Is`A_*)xN={Z zr!)YDO`@PRoNrPFUhL7u4%rr+Bi>mrJ!J_J*zjMluq+@KDE#+)RQaIrkPJ7wKsX&J zt8dL467dLUq$9a}Pfzg%ng0+&i`yhc6+i zFYFuCVqGK``6X2o#sQGfcj}dOgmW^48-P0qVhq~JAaAC5-w%^YYNktyus+DilH}ld z-naa&4$e=%OZ;|n=rxHJ-u{isPjXN=%r@(vm>h9svxzCQtsP(uZ_Y%uT+m@eSJEgV zTZ}qUG6C=H>-w;r{XhjMc^n@^3BQuLsM!{wNSuu34zug?^P*>nko_kpqCs6)gTT=# zzUx1PeOF%A?D18y-{@UDMhfIQ`X3dA5pbOB-*WLd?o8AFN)YJEUyc{kzt!ScweY?4 NU-dw>QW+YX`v1iXX@>v+ literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/flask/sansio/app.py b/env/lib/python3.10/site-packages/flask/sansio/app.py new file mode 100644 index 0000000..0f7d2cb --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/sansio/app.py @@ -0,0 +1,964 @@ +from __future__ import annotations + +import logging +import os +import sys +import typing as t +from datetime import timedelta +from itertools import chain + +from werkzeug.exceptions import Aborter +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.routing import BuildError +from werkzeug.routing import Map +from werkzeug.routing import Rule +from werkzeug.sansio.response import Response +from werkzeug.utils import cached_property +from werkzeug.utils import redirect as _wz_redirect + +from .. import typing as ft +from ..config import Config +from ..config import ConfigAttribute +from ..ctx import _AppCtxGlobals +from ..helpers import _split_blueprint_path +from ..helpers import get_debug_flag +from ..json.provider import DefaultJSONProvider +from ..json.provider import JSONProvider +from ..logging import create_logger +from ..templating import DispatchingJinjaLoader +from ..templating import Environment +from .scaffold import _endpoint_from_view_func +from .scaffold import find_package +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.wrappers import Response as BaseResponse + from .blueprints import Blueprint + from ..testing import FlaskClient + from ..testing import FlaskCliRunner + +T_shell_context_processor = t.TypeVar( + "T_shell_context_processor", bound=ft.ShellContextProcessorCallable +) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) + + +def _make_timedelta(value: timedelta | int | None) -> timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class App(Scaffold): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + #: The class of the object assigned to :attr:`aborter`, created by + #: :meth:`create_aborter`. That object is called by + #: :func:`flask.abort` to raise HTTP errors, and can be + #: called directly as well. + #: + #: Defaults to :class:`werkzeug.exceptions.Aborter`. + #: + #: .. versionadded:: 2.2 + aborter_class = Aborter + + #: The class that is used for the Jinja environment. + #: + #: .. versionadded:: 0.11 + jinja_environment = Environment + + #: The class that is used for the :data:`~flask.g` instance. + #: + #: Example use cases for a custom class: + #: + #: 1. Store arbitrary attributes on flask.g. + #: 2. Add a property for lazy per-request database connectors. + #: 3. Return None instead of AttributeError on unexpected attributes. + #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. + #: + #: In Flask 0.9 this property was called `request_globals_class` but it + #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the + #: flask.g object is now application context scoped. + #: + #: .. versionadded:: 0.10 + app_ctx_globals_class = _AppCtxGlobals + + #: The class that is used for the ``config`` attribute of this app. + #: Defaults to :class:`~flask.Config`. + #: + #: Example use cases for a custom class: + #: + #: 1. Default values for certain config options. + #: 2. Access to config values through attributes in addition to keys. + #: + #: .. versionadded:: 0.11 + config_class = Config + + #: The testing flag. Set this to ``True`` to enable the test mode of + #: Flask extensions (and in the future probably also Flask itself). + #: For example this might activate test helpers that have an + #: additional runtime cost which should not be enabled by default. + #: + #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the + #: default it's implicitly enabled. + #: + #: This attribute can also be configured from the config with the + #: ``TESTING`` configuration key. Defaults to ``False``. + testing = ConfigAttribute("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") + + #: 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 + ) + + json_provider_class: type[JSONProvider] = DefaultJSONProvider + """A subclass of :class:`~flask.json.provider.JSONProvider`. An + instance is created and assigned to :attr:`app.json` when creating + the app. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses + Python's built-in :mod:`json` library. A different provider can use + a different JSON library. + + .. versionadded:: 2.2 + """ + + #: Options that are passed to the Jinja environment in + #: :meth:`create_jinja_environment`. Changing these options after + #: the environment is created (accessing :attr:`jinja_env`) will + #: have no effect. + #: + #: .. versionchanged:: 1.1.0 + #: This is a ``dict`` instead of an ``ImmutableDict`` to allow + #: easier configuration. + #: + jinja_options: dict = {} + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: The map object to use for storing the URL rules and routing + #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`. + #: + #: .. versionadded:: 1.1.0 + url_map_class = Map + + #: The :meth:`test_client` method creates an instance of this test + #: client class. Defaults to :class:`~flask.testing.FlaskClient`. + #: + #: .. versionadded:: 0.7 + test_client_class: type[FlaskClient] | None = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class: type[FlaskCliRunner] | None = None + + default_config: dict + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + "If an instance path is provided it must be absolute." + " A relative path was given instead." + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: An instance of :attr:`aborter_class` created by + #: :meth:`make_aborter`. This is called by :func:`flask.abort` + #: to raise HTTP errors, and can be called directly as well. + #: + #: .. versionadded:: 2.2 + #: Moved from ``flask.abort``, which calls this object. + self.aborter = self.make_aborter() + + self.json: JSONProvider = self.json_provider_class(self) + """Provides access to JSON methods. Functions in ``flask.json`` + will call methods on this provider when the application context + is active. Used for handling JSON requests and responses. + + An instance of :attr:`json_provider_class`. Can be customized by + changing that attribute on a subclass, or by assigning to this + attribute afterwards. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, + uses Python's built-in :mod:`json` library. A different provider + can use a different JSON library. + + .. versionadded:: 2.2 + """ + + #: A list of functions that are called by + #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function is called + #: with ``error``, ``endpoint`` and ``values``. If a function + #: returns ``None`` or raises a ``BuildError``, it is skipped. + #: Otherwise, its return value is returned by ``url_for``. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers: list[ + t.Callable[[Exception, str, dict[str, t.Any]], str] + ] = [] + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs: list[ft.TeardownCallable] = [] + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors: list[ft.ShellContextProcessorCallable] = [] + + #: Maps registered blueprint names to blueprint objects. The + #: dict retains the order the blueprints were registered in. + #: Blueprints can be registered multiple times, this dict does + #: not track how often they were attached. + #: + #: .. versionadded:: 0.7 + self.blueprints: dict[str, Blueprint] = {} + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions: dict = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = self.url_map_class(host_matching=host_matching) + + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_first_request: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called" + " on the application. It has already handled its first" + " request, any changes will not be applied" + " consistently.\n" + "Make sure all imports, decorators, functions, etc." + " needed to set up the application are done before" + " running it." + ) + + @cached_property + def name(self) -> str: # type: ignore + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == "__main__": + fn = getattr(sys.modules["__main__"], "__file__", None) + if fn is None: + return "__main__" + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @cached_property + def logger(self) -> logging.Logger: + """A standard Python :class:`~logging.Logger` for the app, with + the same name as :attr:`name`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will + be set to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be + added. See :doc:`/logging` for more information. + + .. versionchanged:: 1.1.0 + The logger takes the same name as :attr:`name` rather than + hard-coding ``"flask.app"``. + + .. versionchanged:: 1.0.0 + Behavior was simplified. The logger is always named + ``"flask.app"``. The level is only set during configuration, + it doesn't check ``app.debug`` each time. Only one format is + used, not different ones depending on ``app.debug``. No + handlers are removed, and a handler is only added if no + handlers are already configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @cached_property + def jinja_env(self) -> Environment: + """The Jinja environment used to load templates. + + The environment is created the first time this property is + accessed. Changing :attr:`jinja_options` after that will have no + effect. + """ + return self.create_jinja_environment() + + def create_jinja_environment(self) -> Environment: + raise NotImplementedError() + + def make_config(self, instance_relative: bool = False) -> Config: + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults["DEBUG"] = get_debug_flag() + return self.config_class(root_path, defaults) + + def make_aborter(self) -> Aborter: + """Create the object to assign to :attr:`aborter`. That object + is called by :func:`flask.abort` to raise HTTP errors, and can + be called directly as well. + + By default, this creates an instance of :attr:`aborter_class`, + which defaults to :class:`werkzeug.exceptions.Aborter`. + + .. versionadded:: 2.2 + """ + return self.aborter_class() + + def auto_find_instance_path(self) -> str: + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, "instance") + return os.path.join(prefix, "var", f"{self.name}-instance") + + def create_global_jinja_loader(self) -> DispatchingJinjaLoader: + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename: str) -> bool: + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionchanged:: 2.2 + Autoescaping is now enabled by default for ``.svg`` files. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml", ".svg")) + + @property + def debug(self) -> bool: + """Whether debug mode is enabled. When using ``flask run`` to start the + development server, an interactive debugger will be shown for unhandled + exceptions, and the server will be reloaded when code changes. This maps to the + :data:`DEBUG` config key. It may not behave as expected if set late. + + **Do not enable debug mode when deploying in production.** + + Default: ``False`` + """ + return self.config["DEBUG"] + + @debug.setter + def debug(self, value: bool) -> None: + self.config["DEBUG"] = value + + if self.config["TEMPLATES_AUTO_RELOAD"] is None: + self.jinja_env.auto_reload = value + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 0.7 + """ + blueprint.register(self, options) + + def iter_blueprints(self) -> t.ValuesView[Blueprint]: + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return self.blueprints.values() + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + options["endpoint"] = endpoint + methods = options.pop("methods", None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, "methods", None) or ("GET",) + if isinstance(methods, str): + raise TypeError( + "Allowed methods must be a list of strings, for" + ' example: @app.route(..., methods=["POST"])' + ) + methods = {item.upper() for item in methods} + + # Methods that should always be added + required_methods = set(getattr(view_func, "required_methods", ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr( + view_func, "provide_automatic_options", None + ) + + if provide_automatic_options is None: + if "OPTIONS" not in methods: + provide_automatic_options = True + required_methods.add("OPTIONS") + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule = 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: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """A decorator that is used to register custom template test. + You can specify a name for the test, otherwise the function + name will be used. Example:: + + @app.template_test() + def is_prime(n): + if n == 2: + return True + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): + if n % i == 0: + return False + return True + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def teardown_appcontext(self, f: T_teardown) -> T_teardown: + """Registers a function to be called when the application + context is popped. The application context is typically popped + after the request context for each request, at the end of CLI + commands, or after a manually pushed context ends. + + .. code-block:: python + + with app.app_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the app context is + made inactive. Since a request context typically also manages an + application context it would also be called when you pop a + request context. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + .. versionadded:: 0.9 + """ + self.teardown_appcontext_funcs.append(f) + return f + + @setupmethod + def shell_context_processor( + self, f: T_shell_context_processor + ) -> T_shell_context_processor: + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + def _find_error_handler( + self, e: Exception, blueprints: list[str] + ) -> ft.ErrorHandlerCallable | None: + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + names = (*blueprints, None) + + for c in (code, None) if code is not None else (None,): + for name in names: + handler_map = self.error_handler_spec[name][c] + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + return None + + def trap_http_exception(self, e: Exception) -> bool: + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config["TRAP_HTTP_EXCEPTIONS"]: + return True + + trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None + and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def should_ignore_error(self, error: BaseException | None) -> bool: + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def redirect(self, location: str, code: int = 302) -> BaseResponse: + """Create a redirect response object. + + This is called by :func:`flask.redirect`, and can be called + directly as well. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + + .. versionadded:: 2.2 + Moved from ``flask.redirect``, which calls this method. + """ + return _wz_redirect( + location, code=code, Response=self.response_class # type: ignore[arg-type] + ) + + def inject_url_defaults(self, endpoint: str, values: dict) -> None: + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + names: t.Iterable[str | None] = (None,) + + # url_for may be called outside a request context, parse the + # passed endpoint instead of using request.blueprints. + if "." in endpoint: + names = chain( + names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0])) + ) + + for name in names: + if name in self.url_default_functions: + for func in self.url_default_functions[name]: + func(endpoint, values) + + def handle_url_build_error( + self, error: BuildError, endpoint: str, values: dict[str, t.Any] + ) -> str: + """Called by :meth:`.url_for` if a + :exc:`~werkzeug.routing.BuildError` was raised. If this returns + a value, it will be returned by ``url_for``, otherwise the error + will be re-raised. + + Each function in :attr:`url_build_error_handlers` is called with + ``error``, ``endpoint`` and ``values``. If a function returns + ``None`` or raises a ``BuildError``, it is skipped. Otherwise, + its return value is returned by ``url_for``. + + :param error: The active ``BuildError`` being handled. + :param endpoint: The endpoint being built. + :param values: The keyword arguments passed to ``url_for``. + """ + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + except BuildError as e: + # make error available outside except block + error = e + else: + if rv is not None: + return rv + + # Re-raise if called with an active exception, otherwise raise + # the passed in exception. + if error is sys.exc_info()[1]: + raise + + raise error diff --git a/env/lib/python3.10/site-packages/flask/sansio/blueprints.py b/env/lib/python3.10/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..38c92f4 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,626 @@ +from __future__ import annotations + +import os +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from .. import typing as ft +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from .app import App + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) + + +class BlueprintSetupState: + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__( + self, + blueprint: Blueprint, + app: App, + options: t.Any, + first_registration: bool, + ) -> None: + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get("subdomain") + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get("url_prefix") + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + self.name = self.options.get("name", blueprint.name) + self.name_prefix = self.options.get("name_prefix", "") + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get("url_defaults", ())) + + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: t.Callable | None = None, + **options: t.Any, + ) -> None: + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/"))) + else: + rule = self.url_prefix + options.setdefault("subdomain", self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + defaults = self.url_defaults + if "defaults" in options: + defaults = dict(defaults, **options.pop("defaults")) + + self.app.add_url_rule( + rule, + f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."), + view_func, + defaults=defaults, + **options, + ) + + +class Blueprint(Scaffold): + """Represents a blueprint, a collection of routes and other + app-related functions that can be registered on a real application + later. + + A blueprint is an object that allows defining application functions + without requiring an application object ahead of time. It uses the + same decorators as :class:`~flask.Flask`, but defers the need for an + application by recording them for later registration. + + Decorating a function with a blueprint creates a deferred function + that is called with :class:`~flask.blueprints.BlueprintSetupState` + when the blueprint is registered on an application. + + See :doc:`/blueprints` for more information. + + :param name: The name of the blueprint. Will be prepended to each + endpoint name. + :param import_name: The name of the blueprint package, usually + ``__name__``. This helps locate the ``root_path`` for the + blueprint. + :param static_folder: A folder with static files that should be + served by the blueprint's static route. The path is relative to + the blueprint's root path. Blueprint static files are disabled + by default. + :param static_url_path: The url to serve static files from. + Defaults to ``static_folder``. If the blueprint does not have + a ``url_prefix``, the app's static route will take precedence, + and the blueprint's static files won't be accessible. + :param template_folder: A folder with templates that should be added + to the app's template search path. The path is relative to the + blueprint's root path. Blueprint templates are disabled by + default. Blueprint templates have a lower precedence than those + in the app's templates folder. + :param url_prefix: A path to prepend to all of the blueprint's URLs, + to make them distinct from the rest of the app's routes. + :param subdomain: A subdomain that blueprint routes will match on by + default. + :param url_defaults: A dict of default values that blueprint routes + will receive by default. + :param root_path: By default, the blueprint will automatically set + this based on ``import_name``. In certain situations this + automatic detection can fail, so the path can be specified + manually instead. + + .. versionchanged:: 1.1.0 + Blueprints have a ``cli`` group to register nested CLI commands. + The ``cli_group`` parameter controls the name of the group under + the ``flask`` command. + + .. versionadded:: 0.7 + """ + + _got_registered_once = False + + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict | None = None, + root_path: str | None = None, + cli_group: str | None = _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 not name: + raise ValueError("'name' may not be empty.") + + if "." in name: + raise ValueError("'name' may not contain a dot '.' character.") + + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.deferred_functions: list[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: list[tuple[Blueprint, dict]] = [] + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_registered_once: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called on the blueprint" + f" '{self.name}'. It has already been registered at least once, any" + " changes will not be applied consistently.\n" + "Make sure all imports, decorators, functions, etc. needed to set up" + " the blueprint are done before registering it." + ) + + @setupmethod + def record(self, func: 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: App, 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: App, 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.3 + Nested blueprints now correctly apply subdomains. + + .. versionchanged:: 2.1 + Registering the same blueprint with the same name multiple + times is an error. + + .. versionchanged:: 2.0.1 + Nested blueprints are registered with their dotted name. + This allows different blueprints with the same name to be + nested at different locations. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + """ + name_prefix = options.get("name_prefix", "") + self_name = options.get("name", self.name) + name = f"{name_prefix}.{self_name}".lstrip(".") + + if name in app.blueprints: + bp_desc = "this" if app.blueprints[name] is self else "a different" + existing_at = f" '{name}'" if self_name != name else "" + + raise ValueError( + f"The name '{self_name}' is already registered for" + f" {bp_desc} blueprint{existing_at}. Use 'name=' to" + f" provide a unique name." + ) + + first_bp_registration = not any(bp is self for bp in app.blueprints.values()) + first_name_registration = name not in app.blueprints + + app.blueprints[name] = self + self._got_registered_once = True + state = self.make_setup_state(app, options, first_bp_registration) + + if self.has_static_folder: + state.add_url_rule( + f"{self.static_url_path}/", + view_func=self.send_static_file, # type: ignore[attr-defined] + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + self._merge_blueprint_funcs(app, name) + + for deferred in self.deferred_functions: + deferred(state) + + cli_resolved_group = options.get("cli_group", self.cli_group) + + if self.cli.commands: + if cli_resolved_group is None: + app.cli.commands.update(self.cli.commands) + elif cli_resolved_group is _sentinel: + self.cli.name = name + app.cli.add_command(self.cli) + else: + self.cli.name = cli_resolved_group + app.cli.add_command(self.cli) + + for blueprint, bp_options in self._blueprints: + bp_options = bp_options.copy() + bp_url_prefix = bp_options.get("url_prefix") + bp_subdomain = bp_options.get("subdomain") + + if bp_subdomain is None: + bp_subdomain = blueprint.subdomain + + if state.subdomain is not None and bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + "." + state.subdomain + elif bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + elif state.subdomain is not None: + bp_options["subdomain"] = state.subdomain + + if bp_url_prefix is None: + bp_url_prefix = blueprint.url_prefix + + if state.url_prefix is not None and bp_url_prefix is not None: + bp_options["url_prefix"] = ( + state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") + ) + elif bp_url_prefix is not None: + bp_options["url_prefix"] = bp_url_prefix + elif state.url_prefix is not None: + bp_options["url_prefix"] = state.url_prefix + + bp_options["name_prefix"] = name + blueprint.register(app, bp_options) + + def _merge_blueprint_funcs(self, app: App, name: str) -> None: + def extend(bp_dict, 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) + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for + full documentation. + + The URL rule is prefixed with the blueprint's URL prefix. The endpoint name, + used with :func:`url_for`, is prefixed with the blueprint's name. + """ + if endpoint and "." in endpoint: + raise ValueError("'endpoint' may not contain a dot '.' character.") + + if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__: + raise ValueError("'view_func' name may not contain a dot '.' character.") + + self.record( + lambda s: s.add_url_rule( + rule, + endpoint, + view_func, + provide_automatic_options=provide_automatic_options, + **options, + ) + ) + + @setupmethod + def app_template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """Register a template filter, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_app_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a template filter, available in any template rendered by the + application. Works like the :meth:`app_template_filter` decorator. Equivalent to + :meth:`.Flask.add_template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.filters[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """Register a template test, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_app_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a template test, available in any template rendered by the + application. Works like the :meth:`app_template_test` decorator. Equivalent to + :meth:`.Flask.add_template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.tests[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """Register a template global, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_app_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a template global, available in any template rendered by the + application. Works like the :meth:`app_template_global` decorator. Equivalent to + :meth:`.Flask.add_template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.globals[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def before_app_request(self, f: T_before_request) -> T_before_request: + """Like :meth:`before_request`, but before every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.before_request`. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def after_app_request(self, f: T_after_request) -> T_after_request: + """Like :meth:`after_request`, but after every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.after_request`. + """ + self.record_once( + lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def teardown_app_request(self, f: T_teardown) -> T_teardown: + """Like :meth:`teardown_request`, but after every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.teardown_request`. + """ + self.record_once( + lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_context_processor( + self, f: T_template_context_processor + ) -> T_template_context_processor: + """Like :meth:`context_processor`, but for templates rendered by every view, not + only by the blueprint. Equivalent to :meth:`.Flask.context_processor`. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_errorhandler( + self, code: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Like :meth:`errorhandler`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.errorhandler`. + """ + + def decorator(f: T_error_handler) -> T_error_handler: + 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: + """Like :meth:`url_value_preprocessor`, but for every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.url_value_preprocessor`. + """ + self.record_once( + lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Like :meth:`url_defaults`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.url_defaults`. + """ + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/env/lib/python3.10/site-packages/flask/sansio/scaffold.py b/env/lib/python3.10/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..a43f6fd --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,802 @@ +from __future__ import annotations + +import importlib.util +import os +import pathlib +import sys +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from jinja2 import FileSystemLoader +from werkzeug.exceptions import default_exceptions +from werkzeug.exceptions import HTTPException +from werkzeug.utils import cached_property + +from .. import typing as ft +from ..cli import AppGroup +from ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +# a singleton sentinel value for parameter defaults +_sentinel = object() + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) +T_route = t.TypeVar("T_route", bound=ft.RouteCallable) + + +def setupmethod(f: F) -> F: + f_name = f.__name__ + + def wrapper_func(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + self._check_setup_finished(f_name) + return f(self, *args, **kwargs) + + return t.cast(F, update_wrapper(wrapper_func, f)) + + +class Scaffold: + """Common behavior shared between :class:`~flask.Flask` and + :class:`~flask.blueprints.Blueprint`. + + :param import_name: The import name of the module where this object + is defined. Usually :attr:`__name__` should be used. + :param static_folder: Path to a folder of static files to serve. + If this is set, a static route will be added. + :param static_url_path: URL prefix for the static route. + :param template_folder: Path to a folder containing template files. + for rendering. If this is set, a Jinja loader will be added. + :param root_path: The path that static, template, and resource files + are relative to. Typically not set, it is discovered based on + the ``import_name``. + + .. versionadded:: 2.0 + """ + + name: str + _static_folder: str | None = None + _static_url_path: str | None = None + + def __init__( + self, + import_name: str, + static_folder: str | os.PathLike | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike | None = None, + root_path: str | None = None, + ): + #: The name of the package or module that this object belongs + #: to. Do not change this once it is set by the constructor. + self.import_name = import_name + + self.static_folder = static_folder # type: ignore + self.static_url_path = static_url_path + + #: The path to the templates folder, relative to + #: :attr:`root_path`, to add to the template loader. ``None`` if + #: templates should not be added. + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + #: Absolute path to the package on the filesystem. Used to look + #: up resources contained in the package. + self.root_path = root_path + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = AppGroup() + + #: A dictionary mapping endpoint names to view functions. + #: + #: To register a view function, use the :meth:`route` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.view_functions: dict[str, t.Callable] = {} + + #: A data structure of registered error handlers, in the format + #: ``{scope: {code: {class: handler}}}``. The ``scope`` key is + #: the name of a blueprint the handlers are active for, or + #: ``None`` for all requests. The ``code`` key is the HTTP + #: status code for ``HTTPException``, or ``None`` for + #: other exceptions. The innermost dictionary maps exception + #: classes to handler functions. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.error_handler_spec: dict[ + ft.AppOrBlueprintKey, + dict[int | None, dict[type[Exception], ft.ErrorHandlerCallable]], + ] = defaultdict(lambda: defaultdict(dict)) + + #: A data structure of functions to call at the beginning of + #: each request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`before_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.before_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.BeforeRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`after_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.after_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.AfterRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request even if an exception is raised, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`teardown_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.teardown_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.TeardownCallable] + ] = defaultdict(list) + + #: A data structure of functions to call to pass extra context + #: values when rendering templates, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`context_processor` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.template_context_processors: dict[ + ft.AppOrBlueprintKey, list[ft.TemplateContextProcessorCallable] + ] = defaultdict(list, {None: [_default_template_ctx_processor]}) + + #: A data structure of functions to call to modify the keyword + #: arguments passed to the view function, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the + #: :meth:`url_value_preprocessor` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_value_preprocessors: dict[ + ft.AppOrBlueprintKey, + list[ft.URLValuePreprocessorCallable], + ] = defaultdict(list) + + #: A data structure of functions to call to modify the keyword + #: arguments when generating URLs, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`url_defaults` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_default_functions: dict[ + ft.AppOrBlueprintKey, list[ft.URLDefaultCallable] + ] = defaultdict(list) + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.name!r}>" + + def _check_setup_finished(self, f_name: str) -> None: + raise NotImplementedError + + @property + def static_folder(self) -> str | None: + """The absolute path to the configured static folder. ``None`` + if no static folder is set. + """ + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + else: + return None + + @static_folder.setter + def static_folder(self, value: str | os.PathLike | None) -> None: + if value is not None: + value = os.fspath(value).rstrip(r"\/") + + self._static_folder = value + + @property + def has_static_folder(self) -> bool: + """``True`` if :attr:`static_folder` is set. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @property + def static_url_path(self) -> str | None: + """The URL prefix that the static route will be accessible from. + + If it was not configured during init, it is derived from + :attr:`static_folder`. + """ + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + basename = os.path.basename(self.static_folder) + return f"/{basename}".rstrip("/") + + return None + + @static_url_path.setter + def static_url_path(self, value: str | None) -> None: + if value is not None: + value = value.rstrip("/") + + self._static_url_path = value + + @cached_property + def jinja_loader(self) -> FileSystemLoader | None: + """The Jinja loader for this object's templates. By default this + is a class :class:`jinja2.loaders.FileSystemLoader` to + :attr:`template_folder` if it is set. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, self.template_folder)) + else: + return None + + def _method_route( + self, + method: str, + rule: str, + options: dict, + ) -> t.Callable[[T_route], T_route]: + if "methods" in options: + raise TypeError("Use the 'route' decorator to use the 'methods' argument.") + + return self.route(rule, methods=[method], **options) + + @setupmethod + def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["GET"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("GET", rule, options) + + @setupmethod + def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["POST"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("POST", rule, options) + + @setupmethod + def put(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PUT"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PUT", rule, options) + + @setupmethod + def delete(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["DELETE"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("DELETE", rule, options) + + @setupmethod + def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PATCH"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PATCH", rule, options) + + @setupmethod + def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Decorate a view function to register it with the given URL + rule and options. Calls :meth:`add_url_rule`, which has more + details about the implementation. + + .. code-block:: python + + @app.route("/") + def index(): + return "Hello, World!" + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` and + ``OPTIONS`` are added automatically. + + :param rule: The URL rule string. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + + def decorator(f: T_route) -> T_route: + endpoint = options.pop("endpoint", None) + self.add_url_rule(rule, endpoint, f, **options) + return f + + return decorator + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a rule for routing incoming requests and building + URLs. The :meth:`route` decorator is a shortcut to call this + with the ``view_func`` argument. These are equivalent: + + .. code-block:: python + + @app.route("/") + def index(): + ... + + .. code-block:: python + + def index(): + ... + + app.add_url_rule("/", view_func=index) + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. An error + will be raised if a function has already been registered for the + endpoint. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` is + always added automatically, and ``OPTIONS`` is added + automatically by default. + + ``view_func`` does not necessarily need to be passed, but if the + rule should participate in routing an endpoint name must be + associated with a view function at some point with the + :meth:`endpoint` decorator. + + .. code-block:: python + + app.add_url_rule("/", endpoint="index") + + @app.endpoint("index") + def index(): + ... + + If ``view_func`` has a ``required_methods`` attribute, those + methods are added to the passed and automatic methods. If it + has a ``provide_automatic_methods`` attribute, it is used as the + default if the parameter is not passed. + + :param rule: The URL rule string. + :param endpoint: The endpoint name to associate with the rule + and view function. Used when routing and building URLs. + Defaults to ``view_func.__name__``. + :param view_func: The view function to associate with the + endpoint name. + :param provide_automatic_options: Add the ``OPTIONS`` method and + respond to ``OPTIONS`` requests automatically. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + raise NotImplementedError + + @setupmethod + def endpoint(self, endpoint: str) -> t.Callable[[F], F]: + """Decorate a view function to register it for the given + endpoint. Used if a rule is added without a ``view_func`` with + :meth:`add_url_rule`. + + .. code-block:: python + + app.add_url_rule("/ex", endpoint="example") + + @app.endpoint("example") + def example(): + ... + + :param endpoint: The endpoint name to associate with the view + function. + """ + + def decorator(f: F) -> F: + self.view_functions[endpoint] = f + return f + + return decorator + + @setupmethod + def before_request(self, f: T_before_request) -> T_before_request: + """Register a function to run before each request. + + For example, this can be used to open a database connection, or + to load the logged in user from the session. + + .. code-block:: python + + @app.before_request + def load_user(): + if "user_id" in session: + g.user = db.session.get(session["user_id"]) + + The function will be called without any arguments. If it returns + a non-``None`` value, the value is handled as if it was the + return value from the view, and further request handling is + stopped. + + This is available on both app and blueprint objects. When used on an app, this + executes before every request. When used on a blueprint, this executes before + every request that the blueprint handles. To register with a blueprint and + execute before every request, use :meth:`.Blueprint.before_app_request`. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def after_request(self, f: T_after_request) -> T_after_request: + """Register a function to run after each request to this object. + + The function is called with the response object, and must return + a response object. This allows the functions to modify or + replace the response before it is sent. + + If a function raises an exception, any remaining + ``after_request`` functions will not be called. Therefore, this + should not be used for actions that must execute, such as to + close resources. Use :meth:`teardown_request` for that. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.after_app_request`. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f: T_teardown) -> T_teardown: + """Register a function to be called when the request context is + popped. Typically this happens at the end of each request, but + contexts may be pushed manually as well during testing. + + .. code-block:: python + + with app.test_request_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the request context is + made inactive. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.teardown_app_request`. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def context_processor( + self, + f: T_template_context_processor, + ) -> T_template_context_processor: + """Registers a template context processor function. These functions run before + rendering a template. The keys of the returned dict are added as variables + available in the template. + + This is available on both app and blueprint objects. When used on an app, this + is called for every rendered template. When used on a blueprint, this is called + for templates rendered from the blueprint's views. To register with a blueprint + and affect every template, use :meth:`.Blueprint.app_context_processor`. + """ + self.template_context_processors[None].append(f) + return f + + @setupmethod + def url_value_preprocessor( + self, + f: T_url_value_preprocessor, + ) -> T_url_value_preprocessor: + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_value_preprocessor`. + """ + self.url_value_preprocessors[None].append(f) + return f + + @setupmethod + def url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_defaults`. + """ + self.url_default_functions[None].append(f) + return f + + @setupmethod + def errorhandler( + self, code_or_exception: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + This is available on both app and blueprint objects. When used on an app, this + can handle errors from every request. When used on a blueprint, this can handle + errors from requests that the blueprint handles. To register with a blueprint + and affect every request, use :meth:`.Blueprint.app_errorhandler`. + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.register_error_handler(code_or_exception, f) + return f + + return decorator + + @setupmethod + def register_error_handler( + self, + code_or_exception: type[Exception] | int, + f: ft.ErrorHandlerCallable, + ) -> None: + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + exc_class, code = self._get_exc_class_and_code(code_or_exception) + self.error_handler_spec[None][code][exc_class] = f + + @staticmethod + def _get_exc_class_and_code( + exc_class_or_code: type[Exception] | int, + ) -> tuple[type[Exception], int | None]: + """Get the exception class being handled. For HTTP status codes + or ``HTTPException`` subclasses, return both the exception and + status code. + + :param exc_class_or_code: Any exception class, or an HTTP status + code as an integer. + """ + exc_class: type[Exception] + + if isinstance(exc_class_or_code, int): + try: + exc_class = default_exceptions[exc_class_or_code] + except KeyError: + raise ValueError( + f"'{exc_class_or_code}' is not a recognized HTTP" + " error code. Use a subclass of HTTPException with" + " that code instead." + ) from None + else: + exc_class = exc_class_or_code + + if isinstance(exc_class, Exception): + raise TypeError( + f"{exc_class!r} is an instance, not a class. Handlers" + " can only be registered for Exception classes or HTTP" + " error codes." + ) + + if not issubclass(exc_class, Exception): + raise ValueError( + f"'{exc_class.__name__}' is not a subclass of Exception." + " Handlers can only be registered for Exception classes" + " or HTTP error codes." + ) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + +def _endpoint_from_view_func(view_func: t.Callable) -> str: + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, "expected view func if endpoint is not provided." + return view_func.__name__ + + +def _path_is_relative_to(path: pathlib.PurePath, base: str) -> bool: + # Path.is_relative_to doesn't exist until Python 3.9 + try: + path.relative_to(base) + return True + except ValueError: + return False + + +def _find_package_path(import_name): + """Find the path that contains the package or module.""" + root_mod_name, _, _ = import_name.partition(".") + + try: + root_spec = importlib.util.find_spec(root_mod_name) + + if root_spec is None: + raise ValueError("not found") + except (ImportError, ValueError): + # ImportError: the machinery told us it does not exist + # ValueError: + # - the module name was invalid + # - the module name is __main__ + # - we raised `ValueError` due to `root_spec` being `None` + return os.getcwd() + + if root_spec.origin in {"namespace", None}: + # namespace package + package_spec = importlib.util.find_spec(import_name) + + if package_spec is not None and package_spec.submodule_search_locations: + # Pick the path in the namespace that contains the submodule. + package_path = pathlib.Path( + os.path.commonpath(package_spec.submodule_search_locations) + ) + search_location = next( + location + for location in root_spec.submodule_search_locations + if _path_is_relative_to(package_path, location) + ) + else: + # Pick the first path. + search_location = root_spec.submodule_search_locations[0] + + return os.path.dirname(search_location) + elif root_spec.submodule_search_locations: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) + + +def find_package(import_name: str): + """Find the prefix that a package is installed under, and the path + that it would be imported from. + + The prefix is the directory containing the standard directory + hierarchy (lib, bin, etc.). If the package is not installed to the + system (:attr:`sys.prefix`) or a virtualenv (``site-packages``), + ``None`` is returned. + + The path is the entry in :attr:`sys.path` that contains the package + for import. If the package is not installed, it's assumed that the + package was imported from the current working directory. + """ + package_path = _find_package_path(import_name) + py_prefix = os.path.abspath(sys.prefix) + + # installed to the system + if _path_is_relative_to(pathlib.PurePath(package_path), py_prefix): + return py_prefix, package_path + + site_parent, site_folder = os.path.split(package_path) + + # installed to a virtualenv + if site_folder.lower() == "site-packages": + parent, folder = os.path.split(site_parent) + + # Windows (prefix/lib/site-packages) + if folder.lower() == "lib": + return parent, package_path + + # Unix (prefix/lib/pythonX.Y/site-packages) + if os.path.basename(parent).lower() == "lib": + return os.path.dirname(parent), package_path + + # something else (prefix/site-packages) + return site_parent, package_path + + # not installed + return None, package_path diff --git a/env/lib/python3.10/site-packages/flask/sessions.py b/env/lib/python3.10/site-packages/flask/sessions.py new file mode 100644 index 0000000..e5650d6 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/sessions.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import hashlib +import typing as t +from collections.abc import MutableMapping +from datetime import datetime +from datetime import timezone + +from itsdangerous import BadSignature +from itsdangerous import URLSafeTimedSerializer +from werkzeug.datastructures import CallbackDict + +from .json.tag import TaggedJSONSerializer + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .wrappers import Request, Response + + +class SessionMixin(MutableMapping): + """Expands a basic dictionary with session attributes.""" + + @property + def permanent(self) -> bool: + """This reflects the ``'_permanent'`` key in the dict.""" + return self.get("_permanent", False) + + @permanent.setter + def permanent(self, value: bool) -> None: + self["_permanent"] = bool(value) + + #: Some implementations can detect whether a session is newly + #: created, but that is not guaranteed. Use with caution. The mixin + # default is hard-coded ``False``. + new = False + + #: Some implementations can detect changes to the session and set + #: this when that happens. The mixin default is hard coded to + #: ``True``. + modified = True + + #: Some implementations can detect when session data is read or + #: written and set this when that happens. The mixin default is hard + #: coded to ``True``. + accessed = True + + +class SecureCookieSession(CallbackDict, SessionMixin): + """Base class for sessions based on signed cookies. + + This session backend will set the :attr:`modified` and + :attr:`accessed` attributes. It cannot reliably track whether a + session is new (vs. empty), so :attr:`new` remains hard coded to + ``False``. + """ + + #: When data is changed, this is set to ``True``. Only the session + #: dictionary itself is tracked; if the session contains mutable + #: data (for example a nested dict) then this must be set to + #: ``True`` manually when modifying that data. The session cookie + #: will only be written to the response if this is ``True``. + modified = False + + #: When data is read or written, this is set to ``True``. Used by + # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie`` + #: header, which allows caching proxies to cache different pages for + #: different users. + accessed = False + + def __init__(self, initial: t.Any = None) -> None: + def on_update(self) -> None: + self.modified = True + self.accessed = True + + super().__init__(initial, on_update) + + def __getitem__(self, key: str) -> t.Any: + self.accessed = True + return super().__getitem__(key) + + def get(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().get(key, default) + + def setdefault(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().setdefault(key, default) + + +class NullSession(SecureCookieSession): + """Class used to generate nicer error messages if sessions are not + available. Will still allow read-only access to the empty session + but fail on setting. + """ + + def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + raise RuntimeError( + "The session is unavailable because no secret " + "key was set. Set the secret_key on the " + "application to something unique and secret." + ) + + __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # type: ignore # noqa: B950 + del _fail + + +class SessionInterface: + """The basic interface you have to implement in order to replace the + default session interface which uses werkzeug's securecookie + implementation. The only methods you have to implement are + :meth:`open_session` and :meth:`save_session`, the others have + useful defaults which you don't need to change. + + The session object returned by the :meth:`open_session` method has to + provide a dictionary like interface plus the properties and methods + from the :class:`SessionMixin`. We recommend just subclassing a dict + and adding that mixin:: + + class Session(dict, SessionMixin): + pass + + If :meth:`open_session` returns ``None`` Flask will call into + :meth:`make_null_session` to create a session that acts as replacement + if the session support cannot work because some requirement is not + fulfilled. The default :class:`NullSession` class that is created + will complain that the secret key was not set. + + To replace the session interface on an application all you have to do + is to assign :attr:`flask.Flask.session_interface`:: + + app = Flask(__name__) + app.session_interface = MySessionInterface() + + Multiple requests with the same session may be sent and handled + concurrently. When implementing a new session interface, consider + whether reads or writes to the backing store must be synchronized. + There is no guarantee on the order in which the session for each + request is opened or saved, it will occur in the order that requests + begin and end processing. + + .. versionadded:: 0.8 + """ + + #: :meth:`make_null_session` will look here for the class that should + #: be created when a null session is requested. Likewise the + #: :meth:`is_null_session` method will perform a typecheck against + #: this type. + null_session_class = NullSession + + #: A flag that indicates if the session interface is pickle based. + #: This can be used by Flask extensions to make a decision in regards + #: to how to deal with the session object. + #: + #: .. versionadded:: 0.10 + pickle_based = False + + def make_null_session(self, app: Flask) -> NullSession: + """Creates a null session which acts as a replacement object if the + real session support could not be loaded due to a configuration + error. This mainly aids the user experience because the job of the + null session is to still support lookup without complaining but + modifications are answered with a helpful error message of what + failed. + + This creates an instance of :attr:`null_session_class` by default. + """ + return self.null_session_class() + + def is_null_session(self, obj: object) -> bool: + """Checks if a given object is a null session. Null sessions are + not asked to be saved. + + This checks if the object is an instance of :attr:`null_session_class` + by default. + """ + return isinstance(obj, self.null_session_class) + + def get_cookie_name(self, app: Flask) -> str: + """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``.""" + return app.config["SESSION_COOKIE_NAME"] + + def get_cookie_domain(self, app: Flask) -> str | None: + """The value of the ``Domain`` parameter on the session cookie. If not set, + browsers will only send the cookie to the exact domain it was set from. + Otherwise, they will send it to any subdomain of the given value as well. + + Uses the :data:`SESSION_COOKIE_DOMAIN` config. + + .. versionchanged:: 2.3 + Not set by default, does not fall back to ``SERVER_NAME``. + """ + rv = app.config["SESSION_COOKIE_DOMAIN"] + return rv if rv else None + + def get_cookie_path(self, app: Flask) -> str: + """Returns the path for which the cookie should be valid. The + default implementation uses the value from the ``SESSION_COOKIE_PATH`` + config var if it's set, and falls back to ``APPLICATION_ROOT`` or + uses ``/`` if it's ``None``. + """ + return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"] + + def get_cookie_httponly(self, app: Flask) -> bool: + """Returns True if the session cookie should be httponly. This + currently just returns the value of the ``SESSION_COOKIE_HTTPONLY`` + config var. + """ + return app.config["SESSION_COOKIE_HTTPONLY"] + + def get_cookie_secure(self, app: Flask) -> bool: + """Returns True if the cookie should be secure. This currently + just returns the value of the ``SESSION_COOKIE_SECURE`` setting. + """ + return app.config["SESSION_COOKIE_SECURE"] + + def get_cookie_samesite(self, app: Flask) -> str: + """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the + ``SameSite`` attribute. This currently just returns the value of + the :data:`SESSION_COOKIE_SAMESITE` setting. + """ + return app.config["SESSION_COOKIE_SAMESITE"] + + def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None: + """A helper method that returns an expiration date for the session + or ``None`` if the session is linked to the browser session. The + default implementation returns now + the permanent session + lifetime configured on the application. + """ + if session.permanent: + return datetime.now(timezone.utc) + app.permanent_session_lifetime + return None + + def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool: + """Used by session backends to determine if a ``Set-Cookie`` header + should be set for this session cookie for this response. If the session + has been modified, the cookie is set. If the session is permanent and + the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is + always set. + + This check is usually skipped if the session was deleted. + + .. versionadded:: 0.11 + """ + + return session.modified or ( + session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"] + ) + + def open_session(self, app: Flask, request: Request) -> SessionMixin | None: + """This is called at the beginning of each request, after + pushing the request context, before matching the URL. + + This must return an object which implements a dictionary-like + interface as well as the :class:`SessionMixin` interface. + + This will return ``None`` to indicate that loading failed in + some way that is not immediately an error. The request + context will fall back to using :meth:`make_null_session` + in this case. + """ + raise NotImplementedError() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + """This is called at the end of each request, after generating + a response, before removing the request context. It is skipped + if :meth:`is_null_session` returns ``True``. + """ + raise NotImplementedError() + + +session_json_serializer = TaggedJSONSerializer() + + +class SecureCookieSessionInterface(SessionInterface): + """The default session interface that stores sessions in signed cookies + through the :mod:`itsdangerous` module. + """ + + #: the salt that should be applied on top of the secret key for the + #: signing of cookie based sessions. + salt = "cookie-session" + #: the hash function to use for the signature. The default is sha1 + digest_method = staticmethod(hashlib.sha1) + #: the name of the itsdangerous supported key derivation. The default + #: is hmac. + key_derivation = "hmac" + #: A python serializer for the payload. The default is a compact + #: JSON derived serializer with support for some extra Python types + #: such as datetime objects or tuples. + serializer = session_json_serializer + session_class = SecureCookieSession + + def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: + if not app.secret_key: + return None + signer_kwargs = dict( + key_derivation=self.key_derivation, digest_method=self.digest_method + ) + return URLSafeTimedSerializer( + app.secret_key, + salt=self.salt, + serializer=self.serializer, + signer_kwargs=signer_kwargs, + ) + + def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: + s = self.get_signing_serializer(app) + if s is None: + return None + val = request.cookies.get(self.get_cookie_name(app)) + if not val: + return self.session_class() + max_age = int(app.permanent_session_lifetime.total_seconds()) + try: + data = s.loads(val, max_age=max_age) + return self.session_class(data) + except BadSignature: + return self.session_class() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + name = self.get_cookie_name(app) + domain = self.get_cookie_domain(app) + path = self.get_cookie_path(app) + secure = self.get_cookie_secure(app) + samesite = self.get_cookie_samesite(app) + httponly = self.get_cookie_httponly(app) + + # Add a "Vary: Cookie" header if the session was accessed at all. + if session.accessed: + response.vary.add("Cookie") + + # If the session is modified to be empty, remove the cookie. + # If the session is empty, return without setting the cookie. + if not session: + if session.modified: + response.delete_cookie( + name, + domain=domain, + path=path, + secure=secure, + samesite=samesite, + httponly=httponly, + ) + response.vary.add("Cookie") + + return + + if not self.should_set_cookie(app, session): + return + + expires = self.get_expiration_time(app, session) + val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore + response.set_cookie( + name, + val, # type: ignore + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + samesite=samesite, + ) + response.vary.add("Cookie") diff --git a/env/lib/python3.10/site-packages/flask/signals.py b/env/lib/python3.10/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/signals.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from blinker import Namespace + +# This namespace is only for signals provided by Flask itself. +_signals = Namespace() + +template_rendered = _signals.signal("template-rendered") +before_render_template = _signals.signal("before-render-template") +request_started = _signals.signal("request-started") +request_finished = _signals.signal("request-finished") +request_tearing_down = _signals.signal("request-tearing-down") +got_request_exception = _signals.signal("got-request-exception") +appcontext_tearing_down = _signals.signal("appcontext-tearing-down") +appcontext_pushed = _signals.signal("appcontext-pushed") +appcontext_popped = _signals.signal("appcontext-popped") +message_flashed = _signals.signal("message-flashed") diff --git a/env/lib/python3.10/site-packages/flask/templating.py b/env/lib/python3.10/site-packages/flask/templating.py new file mode 100644 index 0000000..8dff8ba --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/templating.py @@ -0,0 +1,221 @@ +from __future__ import annotations + +import typing as t + +from jinja2 import BaseLoader +from jinja2 import Environment as BaseEnvironment +from jinja2 import Template +from jinja2 import TemplateNotFound + +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .helpers import stream_with_context +from .signals import before_render_template +from .signals import template_rendered + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sansio.app import App + from .sansio.scaffold import Scaffold + + +def _default_template_ctx_processor() -> dict[str, t.Any]: + """Default template context processor. Injects `request`, + `session` and `g`. + """ + appctx = _cv_app.get(None) + reqctx = _cv_request.get(None) + rv: dict[str, t.Any] = {} + if appctx is not None: + rv["g"] = appctx.g + if reqctx is not None: + rv["request"] = reqctx.request + rv["session"] = reqctx.session + return rv + + +class Environment(BaseEnvironment): + """Works like a regular Jinja2 environment but has some additional + knowledge of how Flask's blueprint works so that it can prepend the + name of the blueprint to referenced templates if necessary. + """ + + def __init__(self, app: App, **options: t.Any) -> None: + if "loader" not in options: + options["loader"] = app.create_global_jinja_loader() + BaseEnvironment.__init__(self, **options) + self.app = app + + +class DispatchingJinjaLoader(BaseLoader): + """A loader that looks for templates in the application and all + the blueprint folders. + """ + + def __init__(self, app: App) -> None: + self.app = app + + def get_source( # type: ignore + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + if self.app.config["EXPLAIN_TEMPLATE_LOADING"]: + return self._get_source_explained(environment, template) + return self._get_source_fast(environment, template) + + def _get_source_explained( + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + attempts = [] + rv: tuple[str, str | None, t.Callable[[], bool] | None] | None + trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None + + for srcobj, loader in self._iter_loaders(template): + try: + rv = loader.get_source(environment, template) + if trv is None: + trv = rv + except TemplateNotFound: + rv = None + attempts.append((loader, srcobj, rv)) + + from .debughelpers import explain_template_loading_attempts + + explain_template_loading_attempts(self.app, template, attempts) + + if trv is not None: + return trv + raise TemplateNotFound(template) + + def _get_source_fast( + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + for _srcobj, loader in self._iter_loaders(template): + try: + return loader.get_source(environment, template) + except TemplateNotFound: + continue + raise TemplateNotFound(template) + + def _iter_loaders( + self, template: str + ) -> t.Generator[tuple[Scaffold, BaseLoader], None, None]: + loader = self.app.jinja_loader + if loader is not None: + yield self.app, loader + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + yield blueprint, loader + + def list_templates(self) -> list[str]: + result = set() + loader = self.app.jinja_loader + if loader is not None: + result.update(loader.list_templates()) + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + for template in loader.list_templates(): + result.add(template) + + return list(result) + + +def _render(app: Flask, template: Template, context: dict[str, t.Any]) -> str: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + rv = template.render(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + return rv + + +def render_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> str: + """Render a template by name with the given context. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _render(app, template, context) + + +def render_template_string(source: str, **context: t.Any) -> str: + """Render a template from the given source string with the given + context. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _render(app, template, context) + + +def _stream( + app: Flask, template: Template, context: dict[str, t.Any] +) -> t.Iterator[str]: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + def generate() -> t.Iterator[str]: + yield from template.generate(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + rv = generate() + + # If a request context is active, keep it while generating. + if request: + rv = stream_with_context(rv) + + return rv + + +def stream_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> t.Iterator[str]: + """Render a template by name with the given context as a stream. + This returns an iterator of strings, which can be used as a + streaming response from a view. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _stream(app, template, context) + + +def stream_template_string(source: str, **context: t.Any) -> t.Iterator[str]: + """Render a template from the given source string with the given + context as a stream. This returns an iterator of strings, which can + be used as a streaming response from a view. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _stream(app, template, context) diff --git a/env/lib/python3.10/site-packages/flask/testing.py b/env/lib/python3.10/site-packages/flask/testing.py new file mode 100644 index 0000000..69aa785 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/testing.py @@ -0,0 +1,295 @@ +from __future__ import annotations + +import importlib.metadata +import typing as t +from contextlib import contextmanager +from contextlib import ExitStack +from copy import copy +from types import TracebackType +from urllib.parse import urlsplit + +import werkzeug.test +from click.testing import CliRunner +from werkzeug.test import Client +from werkzeug.wrappers import Request as BaseRequest + +from .cli import ScriptInfo +from .sessions import SessionMixin + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.test import TestResponse + + from .app import Flask + + +class EnvironBuilder(werkzeug.test.EnvironBuilder): + """An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the + application. + + :param app: The Flask application to configure the environment from. + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + + def __init__( + self, + app: Flask, + path: str = "/", + base_url: str | None = None, + subdomain: str | None = None, + url_scheme: str | None = None, + *args: t.Any, + **kwargs: t.Any, + ) -> None: + assert not (base_url or subdomain or url_scheme) or ( + base_url is not None + ) != bool( + subdomain or url_scheme + ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + + if base_url is None: + http_host = app.config.get("SERVER_NAME") or "localhost" + app_root = app.config["APPLICATION_ROOT"] + + if subdomain: + http_host = f"{subdomain}.{http_host}" + + if url_scheme is None: + url_scheme = app.config["PREFERRED_URL_SCHEME"] + + url = urlsplit(path) + base_url = ( + f"{url.scheme or url_scheme}://{url.netloc or http_host}" + f"/{app_root.lstrip('/')}" + ) + path = url.path + + if url.query: + sep = b"?" if isinstance(url.query, bytes) else "?" + path += sep + url.query + + self.app = app + super().__init__(path, base_url, *args, **kwargs) + + def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str: # type: ignore + """Serialize ``obj`` to a JSON-formatted string. + + The serialization will be configured according to the config associated + with this EnvironBuilder's ``app``. + """ + return self.app.json.dumps(obj, **kwargs) + + +_werkzeug_version = "" + + +def _get_werkzeug_version() -> str: + global _werkzeug_version + + if not _werkzeug_version: + _werkzeug_version = importlib.metadata.version("werkzeug") + + return _werkzeug_version + + +class FlaskClient(Client): + """Works like a regular Werkzeug test client but has knowledge about + Flask's contexts to defer the cleanup of the request context until + the end of a ``with`` block. For general information about how to + use this class refer to :class:`werkzeug.test.Client`. + + .. versionchanged:: 0.12 + `app.test_client()` includes preset default environment, which can be + set after instantiation of the `app.test_client()` object in + `client.environ_base`. + + Basic usage is outlined in the :doc:`/testing` chapter. + """ + + application: Flask + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + super().__init__(*args, **kwargs) + self.preserve_context = False + self._new_contexts: list[t.ContextManager[t.Any]] = [] + self._context_stack = ExitStack() + self.environ_base = { + "REMOTE_ADDR": "127.0.0.1", + "HTTP_USER_AGENT": f"Werkzeug/{_get_werkzeug_version()}", + } + + @contextmanager + def session_transaction( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Generator[SessionMixin, None, None]: + """When used in combination with a ``with`` statement this opens a + session transaction. This can be used to modify the session that + the test client uses. Once the ``with`` block is left the session is + stored back. + + :: + + with client.session_transaction() as session: + session['value'] = 42 + + Internally this is implemented by going through a temporary test + request context and since session handling could depend on + request variables this function accepts the same arguments as + :meth:`~flask.Flask.test_request_context` which are directly + passed through. + """ + if self._cookies is None: + raise TypeError( + "Cookies are disabled. Create a client with 'use_cookies=True'." + ) + + app = self.application + ctx = app.test_request_context(*args, **kwargs) + self._add_cookies_to_wsgi(ctx.request.environ) + + with ctx: + sess = app.session_interface.open_session(app, ctx.request) + + if sess is None: + raise RuntimeError("Session backend did not open a session.") + + yield sess + resp = app.response_class() + + if app.session_interface.is_null_session(sess): + return + + with ctx: + app.session_interface.save_session(app, sess, resp) + + self._update_cookies_from_response( + ctx.request.host.partition(":")[0], + ctx.request.path, + resp.headers.getlist("Set-Cookie"), + ) + + def _copy_environ(self, other): + out = {**self.environ_base, **other} + + if self.preserve_context: + out["werkzeug.debug.preserve_context"] = self._new_contexts.append + + return out + + def _request_from_builder_args(self, args, kwargs): + kwargs["environ_base"] = self._copy_environ(kwargs.get("environ_base", {})) + builder = EnvironBuilder(self.application, *args, **kwargs) + + try: + return builder.get_request() + finally: + builder.close() + + def open( + self, + *args: t.Any, + buffered: bool = False, + follow_redirects: bool = False, + **kwargs: t.Any, + ) -> TestResponse: + if args and isinstance( + args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest) + ): + if isinstance(args[0], werkzeug.test.EnvironBuilder): + builder = copy(args[0]) + builder.environ_base = self._copy_environ(builder.environ_base or {}) + request = builder.get_request() + elif isinstance(args[0], dict): + request = EnvironBuilder.from_environ( + args[0], app=self.application, environ_base=self._copy_environ({}) + ).get_request() + else: + # isinstance(args[0], BaseRequest) + request = copy(args[0]) + request.environ = self._copy_environ(request.environ) + else: + # request is None + request = self._request_from_builder_args(args, kwargs) + + # Pop any previously preserved contexts. This prevents contexts + # from being preserved across redirects or multiple requests + # within a single block. + self._context_stack.close() + + response = super().open( + request, + buffered=buffered, + follow_redirects=follow_redirects, + ) + response.json_module = self.application.json # type: ignore[assignment] + + # Re-push contexts that were preserved during the request. + while self._new_contexts: + cm = self._new_contexts.pop() + self._context_stack.enter_context(cm) + + return response + + def __enter__(self) -> FlaskClient: + if self.preserve_context: + raise RuntimeError("Cannot nest client invocations") + self.preserve_context = True + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.preserve_context = False + self._context_stack.close() + + +class FlaskCliRunner(CliRunner): + """A :class:`~click.testing.CliRunner` for testing a Flask app's + CLI commands. Typically created using + :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`. + """ + + def __init__(self, app: Flask, **kwargs: t.Any) -> None: + self.app = app + super().__init__(**kwargs) + + def invoke( # type: ignore + self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any + ) -> t.Any: + """Invokes a CLI command in an isolated environment. See + :meth:`CliRunner.invoke ` for + full method documentation. See :ref:`testing-cli` for examples. + + If the ``obj`` argument is not given, passes an instance of + :class:`~flask.cli.ScriptInfo` that knows how to load the Flask + app being tested. + + :param cli: Command object to invoke. Default is the app's + :attr:`~flask.app.Flask.cli` group. + :param args: List of strings to invoke the command with. + + :return: a :class:`~click.testing.Result` object. + """ + if cli is None: + cli = self.app.cli # type: ignore + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/env/lib/python3.10/site-packages/flask/typing.py b/env/lib/python3.10/site-packages/flask/typing.py new file mode 100644 index 0000000..a8c9ba0 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/typing.py @@ -0,0 +1,88 @@ +from __future__ import annotations + +import typing as t + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIApplication # noqa: F401 + from werkzeug.datastructures import Headers # noqa: F401 + from werkzeug.sansio.response import Response # noqa: F401 + +# The possible types that are directly convertible or are a Response object. +ResponseValue = t.Union[ + "Response", + str, + bytes, + t.List[t.Any], + # Only dict is actually accepted, but Mapping allows for TypedDict. + t.Mapping[str, t.Any], + t.Iterator[str], + t.Iterator[bytes], +] + +# the possible types for an individual HTTP header +# This should be a Union, but mypy doesn't pass unless it's a TypeVar. +HeaderValue = t.Union[str, t.List[str], t.Tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[t.Tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + t.Tuple[ResponseValue, HeadersValue], + t.Tuple[ResponseValue, int], + t.Tuple[ResponseValue, int, HeadersValue], + "WSGIApplication", +] + +# Allow any subclass of werkzeug.Response, such as the one from Flask, +# as a callback argument. Using werkzeug.Response directly makes a +# callback annotated with flask.Response fail type checking. +ResponseClass = t.TypeVar("ResponseClass", bound="Response") + +AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named +AfterRequestCallable = t.Union[ + t.Callable[[ResponseClass], ResponseClass], + t.Callable[[ResponseClass], t.Awaitable[ResponseClass]], +] +BeforeFirstRequestCallable = t.Union[ + t.Callable[[], None], t.Callable[[], t.Awaitable[None]] +] +BeforeRequestCallable = t.Union[ + t.Callable[[], t.Optional[ResponseReturnValue]], + t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]], +] +ShellContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]] +TeardownCallable = t.Union[ + t.Callable[[t.Optional[BaseException]], None], + t.Callable[[t.Optional[BaseException]], t.Awaitable[None]], +] +TemplateContextProcessorCallable = t.Union[ + t.Callable[[], t.Dict[str, t.Any]], + t.Callable[[], t.Awaitable[t.Dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, dict], None] +URLValuePreprocessorCallable = t.Callable[[t.Optional[str], t.Optional[dict]], None] + +# This should take Exception, but that either breaks typing the argument +# with a specific exception, or decorating multiple times with different +# exceptions (and using a union type on the argument). +# https://github.com/pallets/flask/issues/4095 +# https://github.com/pallets/flask/issues/4295 +# https://github.com/pallets/flask/issues/4297 +ErrorHandlerCallable = t.Union[ + t.Callable[[t.Any], ResponseReturnValue], + t.Callable[[t.Any], t.Awaitable[ResponseReturnValue]], +] + +RouteCallable = t.Union[ + t.Callable[..., ResponseReturnValue], + t.Callable[..., t.Awaitable[ResponseReturnValue]], +] diff --git a/env/lib/python3.10/site-packages/flask/views.py b/env/lib/python3.10/site-packages/flask/views.py new file mode 100644 index 0000000..c7a2b62 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/views.py @@ -0,0 +1,190 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + + +http_method_funcs = frozenset( + ["get", "post", "head", "options", "delete", "put", "trace", "patch"] +) + + +class View: + """Subclass this class and override :meth:`dispatch_request` to + create a generic class-based view. Call :meth:`as_view` to create a + view function that creates an instance of the class with the given + arguments and calls its ``dispatch_request`` method with any URL + variables. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class Hello(View): + init_every_request = False + + def dispatch_request(self, name): + return f"Hello, {name}!" + + app.add_url_rule( + "/hello/", view_func=Hello.as_view("hello") + ) + + Set :attr:`methods` on the class to change what methods the view + accepts. + + Set :attr:`decorators` on the class to apply a list of decorators to + the generated view function. Decorators applied to the class itself + will not be applied to the generated view function! + + Set :attr:`init_every_request` to ``False`` for efficiency, unless + you need to store request-global data on ``self``. + """ + + #: The methods this view is registered for. Uses the same default + #: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and + #: ``add_url_rule`` by default. + methods: t.ClassVar[t.Collection[str] | None] = None + + #: Control whether the ``OPTIONS`` method is handled automatically. + #: Uses the same default (``True``) as ``route`` and + #: ``add_url_rule`` by default. + provide_automatic_options: t.ClassVar[bool | None] = None + + #: A list of decorators to apply, in order, to the generated view + #: function. Remember that ``@decorator`` syntax is applied bottom + #: to top, so the first decorator in the list would be the bottom + #: decorator. + #: + #: .. versionadded:: 0.8 + decorators: t.ClassVar[list[t.Callable]] = [] + + #: Create a new instance of this view class for every request by + #: default. If a view subclass sets this to ``False``, the same + #: instance is used for every request. + #: + #: A single instance is more efficient, especially if complex setup + #: is done during init. However, storing data on ``self`` is no + #: longer safe across requests, and :data:`~flask.g` should be used + #: instead. + #: + #: .. versionadded:: 2.2 + init_every_request: t.ClassVar[bool] = True + + def dispatch_request(self) -> ft.ResponseReturnValue: + """The actual view function behavior. Subclasses must override + this and return a valid response. Any variables from the URL + rule are passed as keyword arguments. + """ + raise NotImplementedError() + + @classmethod + def as_view( + cls, name: str, *class_args: t.Any, **class_kwargs: t.Any + ) -> ft.RouteCallable: + """Convert the class into a view function that can be registered + for a route. + + By default, the generated view will create a new instance of the + view class for every request and call its + :meth:`dispatch_request` method. If the view class sets + :attr:`init_every_request` to ``False``, the same instance will + be used for every request. + + Except for ``name``, all other arguments passed to this method + are forwarded to the view class ``__init__`` method. + + .. versionchanged:: 2.2 + Added the ``init_every_request`` class attribute. + """ + if cls.init_every_request: + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + self = view.view_class( # type: ignore[attr-defined] + *class_args, **class_kwargs + ) + return current_app.ensure_sync(self.dispatch_request)(**kwargs) + + else: + self = cls(*class_args, **class_kwargs) + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) + + if cls.decorators: + view.__name__ = name + view.__module__ = cls.__module__ + for decorator in cls.decorators: + view = decorator(view) + + # We attach the view class to the view function for two reasons: + # first of all it allows us to easily figure out what class-based + # view this thing came from, secondly it's also used for instantiating + # the view class so you can actually replace it with something else + # for testing purposes and debugging. + view.view_class = cls # type: ignore + view.__name__ = name + view.__doc__ = cls.__doc__ + view.__module__ = cls.__module__ + view.methods = cls.methods # type: ignore + view.provide_automatic_options = cls.provide_automatic_options # type: ignore + return view + + +class MethodView(View): + """Dispatches request methods to the corresponding instance methods. + For example, if you implement a ``get`` method, it will be used to + handle ``GET`` requests. + + This can be useful for defining a REST API. + + :attr:`methods` is automatically set based on the methods defined on + the class. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class CounterAPI(MethodView): + def get(self): + return str(session.get("counter", 0)) + + def post(self): + session["counter"] = session.get("counter", 0) + 1 + return redirect(url_for("counter")) + + app.add_url_rule( + "/counter", view_func=CounterAPI.as_view("counter") + ) + """ + + def __init_subclass__(cls, **kwargs: t.Any) -> None: + super().__init_subclass__(**kwargs) + + if "methods" not in cls.__dict__: + methods = set() + + for base in cls.__bases__: + if getattr(base, "methods", None): + methods.update(base.methods) # type: ignore[attr-defined] + + for key in http_method_funcs: + if hasattr(cls, key): + methods.add(key.upper()) + + if methods: + cls.methods = methods + + def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue: + meth = getattr(self, request.method.lower(), None) + + # If the request method is HEAD and we don't have a handler for it + # retry with GET. + if meth is None and request.method == "HEAD": + meth = getattr(self, "get", None) + + assert meth is not None, f"Unimplemented method {request.method!r}" + return current_app.ensure_sync(meth)(**kwargs) diff --git a/env/lib/python3.10/site-packages/flask/wrappers.py b/env/lib/python3.10/site-packages/flask/wrappers.py new file mode 100644 index 0000000..ef7aa38 --- /dev/null +++ b/env/lib/python3.10/site-packages/flask/wrappers.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.wrappers import Request as RequestBase +from werkzeug.wrappers import Response as ResponseBase + +from . import json +from .globals import current_app +from .helpers import _split_blueprint_path + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.routing import Rule + + +class Request(RequestBase): + """The request object used by default in Flask. Remembers the + matched endpoint and view arguments. + + It is what ends up as :class:`~flask.request`. If you want to replace + the request object used you can subclass this and set + :attr:`~flask.Flask.request_class` to your subclass. + + The request object is a :class:`~werkzeug.wrappers.Request` subclass and + provides all of the attributes Werkzeug defines plus a few Flask + specific ones. + """ + + json_module: t.Any = json + + #: The internal URL rule that matched the request. This can be + #: useful to inspect which methods are allowed for the URL from + #: a before/after handler (``request.url_rule.methods``) etc. + #: Though if the request's method was invalid for the URL rule, + #: the valid list is available in ``routing_exception.valid_methods`` + #: instead (an attribute of the Werkzeug exception + #: :exc:`~werkzeug.exceptions.MethodNotAllowed`) + #: because the request was never internally bound. + #: + #: .. versionadded:: 0.6 + url_rule: Rule | None = None + + #: A dict of view arguments that matched the request. If an exception + #: happened when matching, this will be ``None``. + view_args: dict[str, t.Any] | None = None + + #: If matching the URL failed, this is the exception that will be + #: raised / was raised as part of the request handling. This is + #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or + #: something similar. + routing_exception: Exception | None = None + + @property + def max_content_length(self) -> int | None: # type: ignore + """Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" + if current_app: + return current_app.config["MAX_CONTENT_LENGTH"] + else: + return None + + @property + def endpoint(self) -> str | None: + """The endpoint that matched the request URL. + + This will be ``None`` if matching failed or has not been + performed yet. + + This in combination with :attr:`view_args` can be used to + reconstruct the same URL or a modified URL. + """ + if self.url_rule is not None: + return self.url_rule.endpoint + + return None + + @property + def blueprint(self) -> str | None: + """The registered name of the current blueprint. + + This will be ``None`` if the endpoint is not part of a + blueprint, or if URL matching failed or has not been performed + yet. + + This does not necessarily match the name the blueprint was + created with. It may have been nested, or registered with a + different name. + """ + endpoint = self.endpoint + + if endpoint is not None and "." in endpoint: + return endpoint.rpartition(".")[0] + + return None + + @property + def blueprints(self) -> list[str]: + """The registered names of the current blueprint upwards through + parent blueprints. + + This will be an empty list if there is no current blueprint, or + if URL matching failed. + + .. versionadded:: 2.0.1 + """ + name = self.blueprint + + if name is None: + return [] + + return _split_blueprint_path(name) + + def _load_form_data(self) -> None: + super()._load_form_data() + + # In debug mode we're replacing the files multidict with an ad-hoc + # subclass that raises a different error for key errors. + if ( + current_app + and current_app.debug + and self.mimetype != "multipart/form-data" + and not self.files + ): + from .debughelpers import attach_enctype_error_multidict + + attach_enctype_error_multidict(self) + + def on_json_loading_failed(self, e: ValueError | None) -> t.Any: + try: + return super().on_json_loading_failed(e) + except BadRequest as e: + if current_app and current_app.debug: + raise + + raise BadRequest() from e + + +class Response(ResponseBase): + """The response object that is used by default in Flask. Works like the + response object from Werkzeug but is set to have an HTML mimetype by + default. Quite often you don't have to create this object yourself because + :meth:`~flask.Flask.make_response` will take care of that for you. + + If you want to replace the response object used you can subclass this and + set :attr:`~flask.Flask.response_class` to your subclass. + + .. versionchanged:: 1.0 + JSON support is added to the response, like the request. This is useful + when testing to get the test client response data as JSON. + + .. versionchanged:: 1.0 + + Added :attr:`max_cookie_size`. + """ + + default_mimetype: str | None = "text/html" + + json_module = json + + autocorrect_location_header = False + + @property + def max_cookie_size(self) -> int: # type: ignore + """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. + + See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in + Werkzeug's docs. + """ + if current_app: + return current_app.config["MAX_COOKIE_SIZE"] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2011 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA new file mode 100644 index 0000000..1d935ed --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA @@ -0,0 +1,97 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 2.1.2 +Summary: Safely pass data to untrusted environments and back. +Home-page: https://palletsprojects.com/p/itsdangerous/ +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://itsdangerous.palletsprojects.com/ +Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/itsdangerous/ +Project-URL: Issue Tracker, https://github.com/pallets/itsdangerous/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 + +ItsDangerous +============ + +... so better sign this + +Various helpers to pass data to untrusted environments and to get it +back safe and sound. Data is cryptographically signed to ensure that a +token has not been tampered with. + +It's possible to customize how data is serialized. Data is compressed as +needed. A timestamp can be added and verified automatically while +loading a token. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U itsdangerous + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +Here's how you could generate a token for transmitting a user's id and +name between web requests. + +.. code-block:: python + + from itsdangerous import URLSafeSerializer + auth_s = URLSafeSerializer("secret key", "auth") + token = auth_s.dumps({"id": 5, "name": "itsdangerous"}) + + print(token) + # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg + + data = auth_s.loads(token) + print(data["name"]) + # itsdangerous + + +Donate +------ + +The Pallets organization develops and supports ItsDangerous and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://itsdangerous.palletsprojects.com/ +- Changes: https://itsdangerous.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/ItsDangerous/ +- Source Code: https://github.com/pallets/itsdangerous/ +- Issue Tracker: https://github.com/pallets/itsdangerous/issues/ +- Website: https://palletsprojects.com/p/itsdangerous/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD new file mode 100644 index 0000000..156b2ca --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD @@ -0,0 +1,24 @@ +itsdangerous-2.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +itsdangerous-2.1.2.dist-info/LICENSE.rst,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475 +itsdangerous-2.1.2.dist-info/METADATA,sha256=ThrHIJQ_6XlfbDMCAVe_hawT7IXiIxnTBIDrwxxtucQ,2928 +itsdangerous-2.1.2.dist-info/RECORD,, +itsdangerous-2.1.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous-2.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +itsdangerous-2.1.2.dist-info/top_level.txt,sha256=gKN1OKLk81i7fbWWildJA88EQ9NhnGMSvZqhfz9ICjk,13 +itsdangerous/__init__.py,sha256=n4mkyjlIVn23pgsgCIw0MJKPdcHIetyeRpe5Fwsn8qg,876 +itsdangerous/__pycache__/__init__.cpython-310.pyc,, +itsdangerous/__pycache__/_json.cpython-310.pyc,, +itsdangerous/__pycache__/encoding.cpython-310.pyc,, +itsdangerous/__pycache__/exc.cpython-310.pyc,, +itsdangerous/__pycache__/serializer.cpython-310.pyc,, +itsdangerous/__pycache__/signer.cpython-310.pyc,, +itsdangerous/__pycache__/timed.cpython-310.pyc,, +itsdangerous/__pycache__/url_safe.cpython-310.pyc,, +itsdangerous/_json.py,sha256=wIhs_7-_XZolmyr-JvKNiy_LgAcfevYR0qhCVdlIhg8,450 +itsdangerous/encoding.py,sha256=pgh86snHC76dPLNCnPlrjR5SaYL_M8H-gWRiiLNbhCU,1419 +itsdangerous/exc.py,sha256=VFxmP2lMoSJFqxNMzWonqs35ROII4-fvCBfG0v1Tkbs,3206 +itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous/serializer.py,sha256=zgZ1-U705jHDpt62x_pmLJdryEKDNAbt5UkJtnkcCSw,11144 +itsdangerous/signer.py,sha256=QUH0iX0in-OTptMAXKU5zWMwmOCXn1fsDsubXiGdFN4,9367 +itsdangerous/timed.py,sha256=5CBWLds4Nm8-3bFVC8RxNzFjx6PSwjch8wuZ5cwcHFI,8174 +itsdangerous/url_safe.py,sha256=5bC4jSKOjWNRkWrFseifWVXUnHnPgwOLROjiOwb-eeo,2402 diff --git a/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/REQUESTED b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous-2.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/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..e163955 --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +itsdangerous diff --git a/env/lib/python3.10/site-packages/itsdangerous/__init__.py b/env/lib/python3.10/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..fdb2dfd --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/__init__.py @@ -0,0 +1,19 @@ +from .encoding import base64_decode as base64_decode +from .encoding import base64_encode as base64_encode +from .encoding import want_bytes as want_bytes +from .exc import BadData as BadData +from .exc import BadHeader as BadHeader +from .exc import BadPayload as BadPayload +from .exc import BadSignature as BadSignature +from .exc import BadTimeSignature as BadTimeSignature +from .exc import SignatureExpired as SignatureExpired +from .serializer import Serializer as Serializer +from .signer import HMACAlgorithm as HMACAlgorithm +from .signer import NoneAlgorithm as NoneAlgorithm +from .signer import Signer as Signer +from .timed import TimedSerializer as TimedSerializer +from .timed import TimestampSigner as TimestampSigner +from .url_safe import URLSafeSerializer as URLSafeSerializer +from .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer + +__version__ = "2.1.2" diff --git a/env/lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8587735404fceb61842cd19b64a569fb3030e47d GIT binary patch literal 879 zcmaKq&2G~`6ou_1P8`S1ZyOM6HeC?Y7O_HzQjofUs=@`N*;teK;tb5#(Tr1?yaG?c z`>@ImvEmh2aqp;#5*Cc*qwk!Vxtg(W8AXAEw#$vaaP2xyO2zBji5oTkgt%8nU6~9`cBdEcfMsI%J2I2gqYKMjoEO}T-mPtpu#Wd=I|6n8=Jl^0byT~%Oky7iK0uXx1~+lUvyGtg)PG*^5jOP-+% z(Ip};c(v42w2%H;DA>!k=JoADXrO&T0$Ok>*0yGJ@%HTeOy;E))m-6pbXgX#8#Jkg zUE8Db+1_>=nTo5$cGckhyEh5{1bgeoci}%3*51kFcye-ibbsU9k0FX&Q)g&w8Amrz zHg&k2X^(7^q($PBv`MJRHi6k*Np~n{8hd6P(vpazOR-nc1$2*sJ_Y_#%hcdu^?j7 z6H76T7prPs7N?Wr$FUI=JX-MC7oLNOMP)KxGrlYkvWUYvzvt literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/itsdangerous/__pycache__/_json.cpython-310.pyc b/env/lib/python3.10/site-packages/itsdangerous/__pycache__/_json.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4439260edcef927e8fdbb4e784bc7fa72a726379 GIT binary patch literal 934 zcmZuv&1w`u5bo~z+1bqmBnQFU;B7>A)Z9cQ5>QZB1FHu1()3Q(?#^cC$L=1(hTM{y z;4>uP#n1m*kwC-_DQ`Qe;x@z6Oy)pyZI zBI$}uX!m6k?QOW zq8Yn`wb1L&eCf;J(!ZdS0p18*O!hkKL2nkyNcOwzjvQdu9UJq*x@<&lUX9<3&K@5t z(KMhEq3X7h$x_!%YLce|*%}uE0Gs=ky9+TC!_KH)l`!?ri9i zos$_YF#3glcHo1NjiJ)50xoo36ff*RLnD+hwbCiOq4#g-lhkujBVi`ml~Dnnn#RCV(?+8h+^hKz_$ u8A~Yh5~^G#4Xp20VuLm`>!zsY>NaM&^#3Z_=;>zmXKvj(*b#~7p7#rdmEw;8 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc b/env/lib/python3.10/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5bf2e0d89f2746e67e7224b02c7b7934c8eb5af GIT binary patch literal 1883 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc b/env/lib/python3.10/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04fcb498bf114fb3f5f0fd09f03b66029c168722 GIT binary patch literal 9706 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc b/env/lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d92143f3c9eb8b921d09f7349b2ba9597562338a GIT binary patch literal 2707 zcmbVOOOG2x5bmD$dTnoB29;J zd_?#HFWn@(Bo?>rMis`3ybR;AsDj05EP{+oUW4PrF*a{vT~1tT&6`iJfC-aQLH~%y}SbBN;6X8?b9I_an8k@L1Ys{>BER$ zi3VvNad4Mbg-oI}843xbrE5u7@R=#bZ_QtelYwf1A`C8o32oTIX}E~ZPn0{t}6iLS#B)eA`WSkVaL^C|7TY(twt>| zTiB<`jU*fX0T01hlCjN1cUZ)vX!p}dGWB>0=GjeR@~n5x`F86(cd0MCa~IgBEWq2efG z3U-hVSW~cG8pY#vM+~-BGhr}$rP;y@zc)@&;Y6~nByzU!Ha2lkcv9%T%wlVj4kSYW zH%?lDTm1@x(=B&IZv##5P`Nas+~(w4>k!$36m7XfPty_Ird!^1lI?Yfwg$&2*#i0w zeQk4hf2H6QF0Ad{Vm0)>`0kYyoEP6W0 zGk~y~%cPxTQ5p&|pGoGz(t1s^1f`DC0Q`XOSEw(w4+yWHKtts8vwxGjY~co)uKwrNu%R#%ZKf z7~Ulhc)gQ%MZFoxAs4cKMds@w)~f#b>iPP0(Oiu?qARZD?RF~aBKxuqtEu+}x|3(8 zY9~+BRiedls1h4dTc~=X6_2vEka=I#`!WrYnYG?P?uRAdGSoXD9KU3hsY5N0Rce`^ z^T@KTe}b>Ae;v;P>(lnb-te`ZPit)+iNemC>yPORUn2;kJ-O8iD4J}O+dxqu8dR7q zTU)p75m0%{(ay-(rXa0t%B_QBgUA<04$QJ)mWx&(zAcY%XXG9rpu0dbcje-kU=k0= zvL|1FM^WbeZf}|%xfe~rlplqiicDfRfY}G&Azwjp5GPd<6;9^~UX7)R){bHTcZ0c2cCiDSOImcX973B#^p*8gkctSMHm*PFzn{MpQ2t4!!P<# zI`Q~n$n!W1B|=*4;i47wQytEg7q>akLKRl13;SF)D1yu81VyP~fmv-)nNTnmX$rB- zUW_nXGrNKYN|3{ffd~lf$F)4~p=DW*9H2_cu^xiuZ^x@XU`*odr+Nw={$%)eEKQ(LpE0N8%vx>M9oAU0uNlIopgeGf%u~=NpthTWYw9hM zep>Y7JX49%c<`a3U^nRZ;Pg&j-V`#1uFB$0B%#xSeLTs8iPBytY6{IF#Wn#ae6Fn> z4Uev^y@|?kP)r=qYoJex{ar^Mf$hrIQ5;2a48;uM8F5a4;{x3GvGN2Ypb{<5gi+SP z3$RU_<`XS_`1?-SJu&J305rRXl$d_@`~aFTi1c#;C{MyRcf{)yI4+^{EfhFf-d%Wl z(1Y~KH_&Fzxf^1w9UqXuG;j1H#^%fyHgpwJ+{cC52S?#*{C^~|)fz6FOqfsXw2~rt ae|$VYK#D7@u9&_u6x8W&m%ZoR{r-QIjm|It literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/itsdangerous/_json.py b/env/lib/python3.10/site-packages/itsdangerous/_json.py new file mode 100644 index 0000000..c70d37a --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/_json.py @@ -0,0 +1,16 @@ +import json as _json +import typing as _t + + +class _CompactJSON: + """Wrapper around json module that strips whitespace.""" + + @staticmethod + def loads(payload: _t.Union[str, bytes]) -> _t.Any: + return _json.loads(payload) + + @staticmethod + def dumps(obj: _t.Any, **kwargs: _t.Any) -> str: + kwargs.setdefault("ensure_ascii", False) + kwargs.setdefault("separators", (",", ":")) + return _json.dumps(obj, **kwargs) diff --git a/env/lib/python3.10/site-packages/itsdangerous/encoding.py b/env/lib/python3.10/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..edb04d1 --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/encoding.py @@ -0,0 +1,54 @@ +import base64 +import string +import struct +import typing as _t + +from .exc import BadData + +_t_str_bytes = _t.Union[str, bytes] + + +def want_bytes( + s: _t_str_bytes, encoding: str = "utf-8", errors: str = "strict" +) -> bytes: + if isinstance(s, str): + s = s.encode(encoding, errors) + + return s + + +def base64_encode(string: _t_str_bytes) -> bytes: + """Base64 encode a string of bytes or text. The resulting bytes are + safe to use in URLs. + """ + string = want_bytes(string) + return base64.urlsafe_b64encode(string).rstrip(b"=") + + +def base64_decode(string: _t_str_bytes) -> bytes: + """Base64 decode a URL-safe string of bytes or text. The result is + bytes. + """ + string = want_bytes(string, encoding="ascii", errors="ignore") + string += b"=" * (-len(string) % 4) + + try: + return base64.urlsafe_b64decode(string) + except (TypeError, ValueError) as e: + raise BadData("Invalid base64-encoded data") from e + + +# The alphabet used by base64.urlsafe_* +_base64_alphabet = f"{string.ascii_letters}{string.digits}-_=".encode("ascii") + +_int64_struct = struct.Struct(">Q") +_int_to_bytes = _int64_struct.pack +_bytes_to_int = _t.cast("_t.Callable[[bytes], _t.Tuple[int]]", _int64_struct.unpack) + + +def int_to_bytes(num: int) -> bytes: + return _int_to_bytes(num).lstrip(b"\x00") + + +def bytes_to_int(bytestr: bytes) -> int: + return _bytes_to_int(bytestr.rjust(8, b"\x00"))[0] diff --git a/env/lib/python3.10/site-packages/itsdangerous/exc.py b/env/lib/python3.10/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..c38a6af --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/exc.py @@ -0,0 +1,107 @@ +import typing as _t +from datetime import datetime + +_t_opt_any = _t.Optional[_t.Any] +_t_opt_exc = _t.Optional[Exception] + + +class BadData(Exception): + """Raised if bad data of any sort was encountered. This is the base + for all exceptions that ItsDangerous defines. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str): + super().__init__(message) + self.message = message + + def __str__(self) -> str: + return self.message + + +class BadSignature(BadData): + """Raised if a signature does not match.""" + + def __init__(self, message: str, payload: _t_opt_any = None): + super().__init__(message) + + #: The payload that failed the signature test. In some + #: situations you might still want to inspect this, even if + #: you know it was tampered with. + #: + #: .. versionadded:: 0.14 + self.payload: _t_opt_any = payload + + +class BadTimeSignature(BadSignature): + """Raised if a time-based signature is invalid. This is a subclass + of :class:`BadSignature`. + """ + + def __init__( + self, + message: str, + payload: _t_opt_any = None, + date_signed: _t.Optional[datetime] = None, + ): + super().__init__(message, payload) + + #: If the signature expired this exposes the date of when the + #: signature was created. This can be helpful in order to + #: tell the user how long a link has been gone stale. + #: + #: .. versionchanged:: 2.0 + #: The datetime value is timezone-aware rather than naive. + #: + #: .. versionadded:: 0.14 + self.date_signed = date_signed + + +class SignatureExpired(BadTimeSignature): + """Raised if a signature timestamp is older than ``max_age``. This + is a subclass of :exc:`BadTimeSignature`. + """ + + +class BadHeader(BadSignature): + """Raised if a signed header is invalid in some form. This only + happens for serializers that have a header that goes with the + signature. + + .. versionadded:: 0.24 + """ + + def __init__( + self, + message: str, + payload: _t_opt_any = None, + header: _t_opt_any = None, + original_error: _t_opt_exc = None, + ): + super().__init__(message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header: _t_opt_any = header + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: _t_opt_exc = original_error + + +class BadPayload(BadData): + """Raised if a payload is invalid. This could happen if the payload + is loaded despite an invalid signature, or if there is a mismatch + between the serializer and deserializer. The original exception + that occurred during loading is stored on as :attr:`original_error`. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str, original_error: _t_opt_exc = None): + super().__init__(message) + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: _t_opt_exc = original_error diff --git a/env/lib/python3.10/site-packages/itsdangerous/py.typed b/env/lib/python3.10/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.10/site-packages/itsdangerous/serializer.py b/env/lib/python3.10/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..9f4a84a --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/serializer.py @@ -0,0 +1,295 @@ +import json +import typing as _t + +from .encoding import want_bytes +from .exc import BadPayload +from .exc import BadSignature +from .signer import _make_keys_list +from .signer import Signer + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_kwargs = _t.Dict[str, _t.Any] +_t_opt_kwargs = _t.Optional[_t_kwargs] +_t_signer = _t.Type[Signer] +_t_fallbacks = _t.List[_t.Union[_t_kwargs, _t.Tuple[_t_signer, _t_kwargs], _t_signer]] +_t_load_unsafe = _t.Tuple[bool, _t.Any] +_t_secret_key = _t.Union[_t.Iterable[_t_str_bytes], _t_str_bytes] + + +def is_text_serializer(serializer: _t.Any) -> bool: + """Checks whether a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), str) + + +class Serializer: + """A serializer wraps a :class:`~itsdangerous.signer.Signer` to + enable serializing and securely signing data other than bytes. It + can unsign to verify that the data hasn't been changed. + + The serializer provides :meth:`dumps` and :meth:`loads`, similar to + :mod:`json`, and by default uses :mod:`json` internally to serialize + the data to bytes. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param serializer: An object that provides ``dumps`` and ``loads`` + methods for serializing data to a string. Defaults to + :attr:`default_serializer`, which defaults to :mod:`json`. + :param serializer_kwargs: Keyword arguments to pass when calling + ``serializer.dumps``. + :param signer: A ``Signer`` class to instantiate when signing data. + Defaults to :attr:`default_signer`, which defaults to + :class:`~itsdangerous.signer.Signer`. + :param signer_kwargs: Keyword arguments to pass when instantiating + the ``Signer`` class. + :param fallback_signers: List of signer parameters to try when + unsigning with the default signer fails. Each item can be a dict + of ``signer_kwargs``, a ``Signer`` class, or a tuple of + ``(signer, signer_kwargs)``. Defaults to + :attr:`default_fallback_signers`. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 2.0 + Removed the default SHA-512 fallback signer from + ``default_fallback_signers``. + + .. versionchanged:: 1.1 + Added support for ``fallback_signers`` and configured a default + SHA-512 fallback. This fallback is for users who used the yanked + 1.0.0 release which defaulted to SHA-512. + + .. versionchanged:: 0.14 + The ``signer`` and ``signer_kwargs`` parameters were added to + the constructor. + """ + + #: The default serialization module to use to serialize data to a + #: string internally. The default is :mod:`json`, but can be changed + #: to any object that provides ``dumps`` and ``loads`` methods. + default_serializer: _t.Any = json + + #: The default ``Signer`` class to instantiate when signing data. + #: The default is :class:`itsdangerous.signer.Signer`. + default_signer: _t_signer = Signer + + #: The default fallback signers to try when unsigning fails. + default_fallback_signers: _t_fallbacks = [] + + def __init__( + self, + secret_key: _t_secret_key, + salt: _t_opt_str_bytes = b"itsdangerous", + serializer: _t.Any = None, + serializer_kwargs: _t_opt_kwargs = None, + signer: _t.Optional[_t_signer] = None, + signer_kwargs: _t_opt_kwargs = None, + fallback_signers: _t.Optional[_t_fallbacks] = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key) + + if salt is not None: + salt = want_bytes(salt) + # if salt is None then the signer's default is used + + self.salt = salt + + if serializer is None: + serializer = self.default_serializer + + self.serializer: _t.Any = serializer + self.is_text_serializer: bool = is_text_serializer(serializer) + + if signer is None: + signer = self.default_signer + + self.signer: _t_signer = signer + self.signer_kwargs: _t_kwargs = signer_kwargs or {} + + if fallback_signers is None: + fallback_signers = list(self.default_fallback_signers or ()) + + self.fallback_signers: _t_fallbacks = fallback_signers + self.serializer_kwargs: _t_kwargs = serializer_kwargs or {} + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def load_payload( + self, payload: bytes, serializer: _t.Optional[_t.Any] = None + ) -> _t.Any: + """Loads the encoded object. This function raises + :class:`.BadPayload` if the payload is not valid. The + ``serializer`` parameter can be used to override the serializer + stored on the class. The encoded ``payload`` should always be + bytes. + """ + if serializer is None: + serializer = self.serializer + is_text = self.is_text_serializer + else: + is_text = is_text_serializer(serializer) + + try: + if is_text: + return serializer.loads(payload.decode("utf-8")) + + return serializer.loads(payload) + except Exception as e: + raise BadPayload( + "Could not load the payload because an exception" + " occurred on unserializing the data.", + original_error=e, + ) from e + + def dump_payload(self, obj: _t.Any) -> bytes: + """Dumps the encoded object. The return value is always bytes. + If the internal serializer returns text, the value will be + encoded as UTF-8. + """ + return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) + + def make_signer(self, salt: _t_opt_str_bytes = None) -> Signer: + """Creates a new instance of the signer to be used. The default + implementation uses the :class:`.Signer` base class. + """ + if salt is None: + salt = self.salt + + return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs) + + def iter_unsigners(self, salt: _t_opt_str_bytes = None) -> _t.Iterator[Signer]: + """Iterates over all signers to be tried for unsigning. Starts + with the configured signer, then constructs each signer + specified in ``fallback_signers``. + """ + if salt is None: + salt = self.salt + + yield self.make_signer(salt) + + for fallback in self.fallback_signers: + if isinstance(fallback, dict): + kwargs = fallback + fallback = self.signer + elif isinstance(fallback, tuple): + fallback, kwargs = fallback + else: + kwargs = self.signer_kwargs + + for secret_key in self.secret_keys: + yield fallback(secret_key, salt=salt, **kwargs) + + def dumps(self, obj: _t.Any, salt: _t_opt_str_bytes = None) -> _t_str_bytes: + """Returns a signed string serialized with the internal + serializer. The return value can be either a byte or unicode + string depending on the format of the internal serializer. + """ + payload = want_bytes(self.dump_payload(obj)) + rv = self.make_signer(salt).sign(payload) + + if self.is_text_serializer: + return rv.decode("utf-8") + + return rv + + def dump(self, obj: _t.Any, f: _t.IO, salt: _t_opt_str_bytes = None) -> None: + """Like :meth:`dumps` but dumps into a file. The file handle has + to be compatible with what the internal serializer expects. + """ + f.write(self.dumps(obj, salt)) + + def loads( + self, s: _t_str_bytes, salt: _t_opt_str_bytes = None, **kwargs: _t.Any + ) -> _t.Any: + """Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the + signature validation fails. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + return self.load_payload(signer.unsign(s)) + except BadSignature as err: + last_exception = err + + raise _t.cast(BadSignature, last_exception) + + def load(self, f: _t.IO, salt: _t_opt_str_bytes = None) -> _t.Any: + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe( + self, s: _t_str_bytes, salt: _t_opt_str_bytes = None + ) -> _t_load_unsafe: + """Like :meth:`loads` but without verifying the signature. This + is potentially very dangerous to use depending on how your + serializer works. The return value is ``(signature_valid, + payload)`` instead of just the payload. The first item will be a + boolean that indicates if the signature is valid. This function + never fails. + + Use it for debugging only and if you know that your serializer + module is not exploitable (for example, do not use it with a + pickle serializer). + + .. versionadded:: 0.15 + """ + return self._loads_unsafe_impl(s, salt) + + def _loads_unsafe_impl( + self, + s: _t_str_bytes, + salt: _t_opt_str_bytes, + load_kwargs: _t_opt_kwargs = None, + load_payload_kwargs: _t_opt_kwargs = None, + ) -> _t_load_unsafe: + """Low level helper function to implement :meth:`loads_unsafe` + in serializer subclasses. + """ + if load_kwargs is None: + load_kwargs = {} + + try: + return True, self.loads(s, salt=salt, **load_kwargs) + except BadSignature as e: + if e.payload is None: + return False, None + + if load_payload_kwargs is None: + load_payload_kwargs = {} + + try: + return ( + False, + self.load_payload(e.payload, **load_payload_kwargs), + ) + except BadPayload: + return False, None + + def load_unsafe(self, f: _t.IO, salt: _t_opt_str_bytes = None) -> _t_load_unsafe: + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), salt=salt) diff --git a/env/lib/python3.10/site-packages/itsdangerous/signer.py b/env/lib/python3.10/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..aa12005 --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/signer.py @@ -0,0 +1,257 @@ +import hashlib +import hmac +import typing as _t + +from .encoding import _base64_alphabet +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import want_bytes +from .exc import BadSignature + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_secret_key = _t.Union[_t.Iterable[_t_str_bytes], _t_str_bytes] + + +class SigningAlgorithm: + """Subclasses must implement :meth:`get_signature` to provide + signature generation functionality. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + """Returns the signature for the given key and value.""" + raise NotImplementedError() + + def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool: + """Verifies the given signature matches the expected + signature. + """ + return hmac.compare_digest(sig, self.get_signature(key, value)) + + +class NoneAlgorithm(SigningAlgorithm): + """Provides an algorithm that does not perform any signing and + returns an empty signature. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + return b"" + + +class HMACAlgorithm(SigningAlgorithm): + """Provides signature generation using HMACs.""" + + #: The digest method to use with the MAC algorithm. This defaults to + #: SHA1, but can be changed to any other function in the hashlib + #: module. + default_digest_method: _t.Any = staticmethod(hashlib.sha1) + + def __init__(self, digest_method: _t.Any = None): + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: _t.Any = digest_method + + def get_signature(self, key: bytes, value: bytes) -> bytes: + mac = hmac.new(key, msg=value, digestmod=self.digest_method) + return mac.digest() + + +def _make_keys_list(secret_key: _t_secret_key) -> _t.List[bytes]: + if isinstance(secret_key, (str, bytes)): + return [want_bytes(secret_key)] + + return [want_bytes(s) for s in secret_key] + + +class Signer: + """A signer securely signs bytes, then unsigns them to verify that + the value hasn't been changed. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param sep: Separator between the signature and value. + :param key_derivation: How to derive the signing key from the secret + key and salt. Possible values are ``concat``, ``django-concat``, + or ``hmac``. Defaults to :attr:`default_key_derivation`, which + defaults to ``django-concat``. + :param digest_method: Hash function to use when generating the HMAC + signature. Defaults to :attr:`default_digest_method`, which + defaults to :func:`hashlib.sha1`. Note that the security of the + hash alone doesn't apply when used intermediately in HMAC. + :param algorithm: A :class:`SigningAlgorithm` instance to use + instead of building a default :class:`HMACAlgorithm` with the + ``digest_method``. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 0.18 + ``algorithm`` was added as an argument to the class constructor. + + .. versionchanged:: 0.14 + ``key_derivation`` and ``digest_method`` were added as arguments + to the class constructor. + """ + + #: The default digest method to use for the signer. The default is + #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or + #: compatible object. Note that the security of the hash alone + #: doesn't apply when used intermediately in HMAC. + #: + #: .. versionadded:: 0.14 + default_digest_method: _t.Any = staticmethod(hashlib.sha1) + + #: The default scheme to use to derive the signing key from the + #: secret key and salt. The default is ``django-concat``. Possible + #: values are ``concat``, ``django-concat``, and ``hmac``. + #: + #: .. versionadded:: 0.14 + default_key_derivation: str = "django-concat" + + def __init__( + self, + secret_key: _t_secret_key, + salt: _t_opt_str_bytes = b"itsdangerous.Signer", + sep: _t_str_bytes = b".", + key_derivation: _t.Optional[str] = None, + digest_method: _t.Optional[_t.Any] = None, + algorithm: _t.Optional[SigningAlgorithm] = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key) + self.sep: bytes = want_bytes(sep) + + if self.sep in _base64_alphabet: + raise ValueError( + "The given separator cannot be used because it may be" + " contained in the signature itself. ASCII letters," + " digits, and '-_=' must not be used." + ) + + if salt is not None: + salt = want_bytes(salt) + else: + salt = b"itsdangerous.Signer" + + self.salt = salt + + if key_derivation is None: + key_derivation = self.default_key_derivation + + self.key_derivation: str = key_derivation + + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: _t.Any = digest_method + + if algorithm is None: + algorithm = HMACAlgorithm(self.digest_method) + + self.algorithm: SigningAlgorithm = algorithm + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def derive_key(self, secret_key: _t_opt_str_bytes = None) -> bytes: + """This method is called to derive the key. The default key + derivation choices can be overridden here. Key derivation is not + intended to be used as a security method to make a complex key + out of a short password. Instead you should use large random + secret keys. + + :param secret_key: A specific secret key to derive from. + Defaults to the last item in :attr:`secret_keys`. + + .. versionchanged:: 2.0 + Added the ``secret_key`` parameter. + """ + if secret_key is None: + secret_key = self.secret_keys[-1] + else: + secret_key = want_bytes(secret_key) + + if self.key_derivation == "concat": + return _t.cast(bytes, self.digest_method(self.salt + secret_key).digest()) + elif self.key_derivation == "django-concat": + return _t.cast( + bytes, self.digest_method(self.salt + b"signer" + secret_key).digest() + ) + elif self.key_derivation == "hmac": + mac = hmac.new(secret_key, digestmod=self.digest_method) + mac.update(self.salt) + return mac.digest() + elif self.key_derivation == "none": + return secret_key + else: + raise TypeError("Unknown key derivation method") + + def get_signature(self, value: _t_str_bytes) -> bytes: + """Returns the signature for the given value.""" + value = want_bytes(value) + key = self.derive_key() + sig = self.algorithm.get_signature(key, value) + return base64_encode(sig) + + def sign(self, value: _t_str_bytes) -> bytes: + """Signs the given string.""" + value = want_bytes(value) + return value + self.sep + self.get_signature(value) + + def verify_signature(self, value: _t_str_bytes, sig: _t_str_bytes) -> bool: + """Verifies the signature for the given value.""" + try: + sig = base64_decode(sig) + except Exception: + return False + + value = want_bytes(value) + + for secret_key in reversed(self.secret_keys): + key = self.derive_key(secret_key) + + if self.algorithm.verify_signature(key, value, sig): + return True + + return False + + def unsign(self, signed_value: _t_str_bytes) -> bytes: + """Unsigns the given string.""" + signed_value = want_bytes(signed_value) + + if self.sep not in signed_value: + raise BadSignature(f"No {self.sep!r} found in value") + + value, sig = signed_value.rsplit(self.sep, 1) + + if self.verify_signature(value, sig): + return value + + raise BadSignature(f"Signature {sig!r} does not match", payload=value) + + def validate(self, signed_value: _t_str_bytes) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid. + """ + try: + self.unsign(signed_value) + return True + except BadSignature: + return False diff --git a/env/lib/python3.10/site-packages/itsdangerous/timed.py b/env/lib/python3.10/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..cad8da3 --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/timed.py @@ -0,0 +1,234 @@ +import time +import typing +import typing as _t +from datetime import datetime +from datetime import timezone + +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import bytes_to_int +from .encoding import int_to_bytes +from .encoding import want_bytes +from .exc import BadSignature +from .exc import BadTimeSignature +from .exc import SignatureExpired +from .serializer import Serializer +from .signer import Signer + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_opt_int = _t.Optional[int] + +if _t.TYPE_CHECKING: + import typing_extensions as _te + + +class TimestampSigner(Signer): + """Works like the regular :class:`.Signer` but also records the time + of the signing and can be used to expire signatures. The + :meth:`unsign` method can raise :exc:`.SignatureExpired` if the + unsigning failed because the signature is expired. + """ + + def get_timestamp(self) -> int: + """Returns the current timestamp. The function must return an + integer. + """ + return int(time.time()) + + def timestamp_to_datetime(self, ts: int) -> datetime: + """Convert the timestamp from :meth:`get_timestamp` into an + aware :class`datetime.datetime` in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + return datetime.fromtimestamp(ts, tz=timezone.utc) + + def sign(self, value: _t_str_bytes) -> bytes: + """Signs the given string and also attaches time information.""" + value = want_bytes(value) + timestamp = base64_encode(int_to_bytes(self.get_timestamp())) + sep = want_bytes(self.sep) + value = value + sep + timestamp + return value + sep + self.get_signature(value) + + # Ignore overlapping signatures check, return_timestamp is the only + # parameter that affects the return type. + + @typing.overload + def unsign( # type: ignore + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: "_te.Literal[False]" = False, + ) -> bytes: + ... + + @typing.overload + def unsign( + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: "_te.Literal[True]" = True, + ) -> _t.Tuple[bytes, datetime]: + ... + + def unsign( + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: bool = False, + ) -> _t.Union[_t.Tuple[bytes, datetime], bytes]: + """Works like the regular :meth:`.Signer.unsign` but can also + validate the time. See the base docstring of the class for + the general behavior. If ``return_timestamp`` is ``True`` the + timestamp of the signature will be returned as an aware + :class:`datetime.datetime` object in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + try: + result = super().unsign(signed_value) + sig_error = None + except BadSignature as e: + sig_error = e + result = e.payload or b"" + + sep = want_bytes(self.sep) + + # If there is no timestamp in the result there is something + # seriously wrong. In case there was a signature error, we raise + # that one directly, otherwise we have a weird situation in + # which we shouldn't have come except someone uses a time-based + # serializer on non-timestamp data, so catch that. + if sep not in result: + if sig_error: + raise sig_error + + raise BadTimeSignature("timestamp missing", payload=result) + + value, ts_bytes = result.rsplit(sep, 1) + ts_int: _t_opt_int = None + ts_dt: _t.Optional[datetime] = None + + try: + ts_int = bytes_to_int(base64_decode(ts_bytes)) + except Exception: + pass + + # Signature is *not* okay. Raise a proper error now that we have + # split the value and the timestamp. + if sig_error is not None: + if ts_int is not None: + try: + ts_dt = self.timestamp_to_datetime(ts_int) + except (ValueError, OSError, OverflowError) as exc: + # Windows raises OSError + # 32-bit raises OverflowError + raise BadTimeSignature( + "Malformed timestamp", payload=value + ) from exc + + raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt) + + # Signature was okay but the timestamp is actually not there or + # malformed. Should not happen, but we handle it anyway. + if ts_int is None: + raise BadTimeSignature("Malformed timestamp", payload=value) + + # Check timestamp is not older than max_age + if max_age is not None: + age = self.get_timestamp() - ts_int + + if age > max_age: + raise SignatureExpired( + f"Signature age {age} > {max_age} seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if age < 0: + raise SignatureExpired( + f"Signature age {age} < 0 seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if return_timestamp: + return value, self.timestamp_to_datetime(ts_int) + + return value + + def validate(self, signed_value: _t_str_bytes, max_age: _t_opt_int = None) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid.""" + try: + self.unsign(signed_value, max_age=max_age) + return True + except BadSignature: + return False + + +class TimedSerializer(Serializer): + """Uses :class:`TimestampSigner` instead of the default + :class:`.Signer`. + """ + + default_signer: _t.Type[TimestampSigner] = TimestampSigner + + def iter_unsigners( + self, salt: _t_opt_str_bytes = None + ) -> _t.Iterator[TimestampSigner]: + return _t.cast("_t.Iterator[TimestampSigner]", super().iter_unsigners(salt)) + + # TODO: Signature is incompatible because parameters were added + # before salt. + + def loads( # type: ignore + self, + s: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: bool = False, + salt: _t_opt_str_bytes = None, + ) -> _t.Any: + """Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the + signature validation fails. If a ``max_age`` is provided it will + ensure the signature is not older than that time in seconds. In + case the signature is outdated, :exc:`.SignatureExpired` is + raised. All arguments are forwarded to the signer's + :meth:`~TimestampSigner.unsign` method. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + base64d, timestamp = signer.unsign( + s, max_age=max_age, return_timestamp=True + ) + payload = self.load_payload(base64d) + + if return_timestamp: + return payload, timestamp + + return payload + except SignatureExpired: + # The signature was unsigned successfully but was + # expired. Do not try the next signer. + raise + except BadSignature as err: + last_exception = err + + raise _t.cast(BadSignature, last_exception) + + def loads_unsafe( # type: ignore + self, + s: _t_str_bytes, + max_age: _t_opt_int = None, + salt: _t_opt_str_bytes = None, + ) -> _t.Tuple[bool, _t.Any]: + return self._loads_unsafe_impl(s, salt, load_kwargs={"max_age": max_age}) diff --git a/env/lib/python3.10/site-packages/itsdangerous/url_safe.py b/env/lib/python3.10/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..d5a9b0c --- /dev/null +++ b/env/lib/python3.10/site-packages/itsdangerous/url_safe.py @@ -0,0 +1,80 @@ +import typing as _t +import zlib + +from ._json import _CompactJSON +from .encoding import base64_decode +from .encoding import base64_encode +from .exc import BadPayload +from .serializer import Serializer +from .timed import TimedSerializer + + +class URLSafeSerializerMixin(Serializer): + """Mixed in with a regular serializer it will attempt to zlib + compress the string to make it shorter if necessary. It will also + base64 encode the string so that it can safely be placed in a URL. + """ + + default_serializer = _CompactJSON + + def load_payload( + self, + payload: bytes, + *args: _t.Any, + serializer: _t.Optional[_t.Any] = None, + **kwargs: _t.Any, + ) -> _t.Any: + decompress = False + + if payload.startswith(b"."): + payload = payload[1:] + decompress = True + + try: + json = base64_decode(payload) + except Exception as e: + raise BadPayload( + "Could not base64 decode the payload because of an exception", + original_error=e, + ) from e + + if decompress: + try: + json = zlib.decompress(json) + except Exception as e: + raise BadPayload( + "Could not zlib decompress the payload before decoding the payload", + original_error=e, + ) from e + + return super().load_payload(json, *args, **kwargs) + + def dump_payload(self, obj: _t.Any) -> bytes: + json = super().dump_payload(obj) + is_compressed = False + compressed = zlib.compress(json) + + if len(compressed) < (len(json) - 1): + json = compressed + is_compressed = True + + base64d = base64_encode(json) + + if is_compressed: + base64d = b"." + base64d + + return base64d + + +class URLSafeSerializer(URLSafeSerializerMixin, Serializer): + """Works like :class:`.Serializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + + +class URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer): + """Works like :class:`.TimedSerializer` but dumps and loads into a + URL safe string consisting of the upper and lowercase character of + the alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ diff --git a/env/lib/python3.10/site-packages/jinja2/__init__.py b/env/lib/python3.10/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..e323926 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/__init__.py @@ -0,0 +1,37 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.2" diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3969ec1fe67e1ccb8bb81f2db34373cad1975747 GIT binary patch literal 1615 zcmbW1%WmT~6ozHTj&Jhav2%}-%(Td2tafHw6m2pSpv7bmjHefHQGu3DZDlA@AnDZ3 zs=F@w0)2(Pl6OT{eTA-i$W*pF%SzCXk3SEuI;5!As}4SYy!aJgSx}L=JJHT$E?IBv0}=!&}H(WXo~^xj+h*i>#PzlWoh}$R$#;Tw>*Cc zTtTjpn&m38OI*t}ZMliuAsx#tx z44u_vMk_Pk2z@PPJi?$}=DnS99Vd{*wliOC1a~uYWH&2|ZG6Kc_z^cM%AD#YRq$HS z2+Ty>tEq^?b-DU74)vt2CLcOR2nZ~JezDf{e-@UfQbp_%p|}~d0Yv`Hb+|GL^p#gn*}#yKxJV6m@>wxn-n)vaD^4AdAM{Hg*-}A=so<5^pv~mW@=5m@7}#jJQVXD9aMF ze^1GVv6@C&M%qR?M!H6NMs`q^CHa^@vTv+`kzFHuM)pyb#hH$ok_W~(G;(C**vN?y z4`o>kf_sqWs0G3Aj=V4xM*jZ6pNa(hF_jOPRsO9MceqE&|8{ice+T0c9-9Q-;csN% z;|};N9{Z_1@wj!L_$t=$EPc!w<=>fG~nK))g?;7aSLwl I|G(w@KgY+y!T=Fdx3=;y^1=Oo zp%(eYXFtXQzx~~x|2q1c#QtvoBl~5NeVKi&u-DVq^PBih;wE*IzR7-7U|*fS$+I`L zH@({;yFI_HvD?ON`?hmyuv_bE_D%1d$=kEVXmg z&SN4|yF~3ewKZzbr~_vwNgba$aOw%tv!v%phf|kHS4i)X?vOqp15P7JhEE2ZW}3__ z!V5BCHDxmEWNKuhCv#3+c)LmJ`qYKjN|BW%D@PWrmP}TWtP)vuvNXC(&?PK(g6s@J zj_iE|nd}nvBu2dy^-y+F2$U)hW$$3Rik(@d?8uhVRKS_O``mnkwa$$9IFKJYy z(Fs(IMtvH&GUEXUj-WzeZz_@$F-IoX*?poYMZ?4DP5yBN8;n5Mo1Yy3A=8L$rh`(GU z3v7`*UnDOU$tF~9kvdtVE*GxN7Ot}x%oih-Ek^S@$zXSqeU~WTB~C@z7G;l#@>HBw z#c55P^~9MY)PztoLd^?RV?u3Cb~gb{Z7&YEY1e48wI$z;6{p z5~M)}9E6EOFb+j%!E&YlwP=9 zZwSKedhga2zIZ{7Kly zWEd1pbYC>Rpx6yX7nv!VDNbiWadrqXI||PF6;KT-=_bRV11l7LfKya(OO;GI6nS8T z!U`%c5)dy^L8XI>sdR=QH0xb32r33D#u*Yu4P1o64yxhzrYdDXE)*vKo~m>KG|&LJ zu&QJPRjmM_6@zLs1<~C9R>e2!TQzHc`hySdzrD8;d;8wwt>@e88xY&8dwa2+O+B*n zUHrHHZ}|6W^y${~SoG2A&R^DIJJDb6Y(0xT-rJ4-`r*%`zllA1`1on;dF)qPPo8YV zqOr|CMK{(TMYliSd%Csx@rOVBD7w487h~J2kN>#(B(@uUw!Zmn^+(a)udl^6_tyWg l9^3hF`}4OCe)4>4?X!*8Pgk((?gI=DBHy`xZ{@*%{tE^+`)L3G literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cdae9a781fac64e07bad0bbc76ee406c785b2ca GIT binary patch literal 2727 zcma)7UvCpf5Z~Rqv(NwX#|dcytw6jKQ?MbCXr&_5l+u=}wNjD>$q1b;-i>p{zB7C4 zKrBZhB2_>YmHGv$MCwEN3VrQI=-a+kec~(d0G-)OVjF~7C%ZR0J3G7c+uzJag+i9V z@9%}5#P1nG{=vcU4|L=+Xz?G=al&bf)RHf)F&ML!)wXLkMV$q*Q*%JJxzkFu)3vmb zQy{xFmlDDDGdz7jYgz8{%r2?rL|zocm>3rmVp0^v6sM2rhFhEFS;3kopv~~~9O3D8 z27L~`HqZ0Iu3dXCGnN_8T3lMXam!m=UcUKN^}8F@m1R&n52W9TUr?}uk?Sq_al9xSAWwEc^u(s$^6F8j z#6zX&Y8?%aehdWbu*DM~?2&cKDQCOxHtpl~R&`{712!pWQ_$jHp;Kg^KCuocnsd@6 zPg$QT(qvsC=QveX)89YesbK6qcCsyC$ z>1PZi(r1YMGi#6R(LJ_jfzK?@?ZOJMwVyEgjmq_HlzF~yd(hzcg{roF*@$&Y3e}b2 zNHB;52DFU96c2+@tPfrb^p&KZbrSidxzYV$YAa!uoS6U0C~^ zNCfbuU)hM-qO#`89v8B*B%`LNtGKede7$m8tS#3!L|d#xjYdmUM7UXL1#6YgmfDEI zh4SS~l{ir1V#lxF^BW?rG=s3|&sWSoURMRJxZK&2W3Z380KC2;?ae3io4ySEP?fK? zqPpLTua&u|N77f39H@>C{caql!6#no0EecHNJvb#k|T5Qk$LP2(CHk+5XdNOi%^+^ z$#I-RD3WdxB|Pygv=~o3O-q)}dR{x?-Ink?;H($=ZItq!cfaemk`b~Q2plv*!HusH zlQXbhr@I~QE5Yk9IQ}7xZD^;V#h*a;g!T!rfdMn}c%_{D2)VcoJd!7XO(Y1&sR#u5dR?9 zL?u6fHINza!>42!4+%R?fkGN6GRO2pBE@K#r7q2~88+?M=^{vZIz#Q8OH<6Iy)*v> z&Jjn@lRSr=!Tm#&%#MW-4~Tw@7Y*>AlO+(e1EsPnBt9K)B?wyn2`&B{x*e!-$Sy@U zArBPWw>Yp3(?r?(4oFmS#q5Bxy+Yb|kS^=>Jp zZMD@Ax(GG9-Ht-9BZGFJf=v+*a!;p&Fz!HI(YYY@kCp@8=fPzX_JDI)zpEn8Sbd5C zVBqXg9?;FQBF!^-2^3Jzl#qCcm*-XahcJl3J8&{Aa5oPp;B*(xsPfS8?#tq^4OAMi z89@%ohGAX@A+Cb3!w@-mEt#BCbf0m9&^+m777R+a3BDw&gp&LDE1&_?&)o8ajs-nb;k1mJ|R7?H*%T;&t75V#87$C8-9$m9iRzy?>u)BcU zI)>CbbDV94_a;Vde+$dZ(T5@(WRQC`d8@ABwZ>RlT;kF^{+TRtt=S7_EtX@Hy=E-? KDv?|^_Ud1zYk?F1 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03e60b78a59f95fd865a6c5129825719c0f0601e GIT binary patch literal 13961 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 ym%$<q=jxnSF literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..302bdde1666bb5972a0c36e916961e0dea37deb3 GIT binary patch literal 54564 zcmbTf34k0&c`rWG({t?X?5WjiCCk!SmgF5tUfJ0A5V9>p zF%?(NTztyGZ(=Sn?@qaK#<_FJ`P5WO?vr!r`OH*C?o)F;^VzAa+^6Sy=W|nia-W&& zpC6bSkoz9o4^9o@KC61?hUSN-hUGptw`zW5YDDh)=2p*-PL0ZaKknB|t&#fy+>cF- z$^9Vi*G{1oC}#-w>!#Mp{qWrI{54b8$o;Ch_4C(GT`Tt^a~tM2PHmL?)ws`3<>h{K z?z;I+Q=8(kvNLV{|BsT*ykp->*4-Kn;nNGONp zAkB8Q18HvRNON;rnj6&w(!8w4>Dk$HlbTdFqm*0J%hWCER+M^cc>*1LDRHwY&l<&EinA(Hq`_%(@ zexSSw&wKHFP`wh*uaxI|@%$?FAf6vA@5B51@cfV};JG00_bcactnjdR)4tmLLS?R8 z&sS>-;f$`$=Nl)>`Gu0Mmvz2UZPfCQoNt`0RrAwGG4XYd?#V*j@1L$!8|8D2`BJrX zqO2LSxS&dna`CJ#Ei6b(=5Rw-swWOUjJL_@lch=(H$9d5sq*==HLdWFD%Yn=3uWFt zRMMvw7rq`x`AjbL!OiHA^8CUa%H3N>g&LJwb-&g%elLCa{QU9STphRlkL^8FeDLAD z_Z9a(cyRAw#0-ZqkL*3P_o4kq_8&s*U>JL7|KW!pd~APP%10;f+kfETOlsA|87lUT9S2E1qdq@sU!!zE_{Xixj{xU1~7LB;fN{rCw=B?RxiD&s21+I$y3f z{P=+hq(~mGEmoE1+;x}dTzA)%_}!j!H-2_|&hEQ>r&9G&)mj4}FJyeDeA;)aW#2i` z@ZA#)KF#574tM$*K#1^ZRH}Y_#!u;TV^LS93Ao@7$Rg2Y*T2xVTvN`YRDMW3#}Ai*bET)0vIW zI`wN9vy^DY`Fz>A;5OZ6{8R$(8S6Hk%c#t=$j1~jiAt=Q_(1#}@x!s_oS!*U!^pw#_LFDWF@>bwf^X{^7>qO6hQQBM%V&#h>`6JtCfuU3u-! zlePKs&f_KRsj}Yrh_20+ryKR1j~(8(^YQZW!_z0r^W`J86DQ`%JImEGJLf9LcP_{@ zxn<(!n|9(`s>N{sE)!EX^c21kArY9E8n@`RxR;PF1dv$izusayfIJx+U z<82Jug0WR^OzfVkO_%2CcTcdI%u`5f=J4J9=N7adZ}^G5)$^L*_TA}Hy`k6Ow%|xx z^sTtpFJo{sgIf^zeQh7uj;Q(=0w<1tS6y7euj}-`IGodWGLutV&|7h%3ka5twjM;X z1}_k-jbOZ?W0l)TV8q2{GBVCmD*a6EV*En9iLNVTCQXM(xvgGVHhfqzhtMiq^>-oQ zV402U8#o|v=bS;Oa-gXAv$6L&%DI%d9FODO5(d$1l7mN{utY@SQzpK;UUIIK!$pZP z<+hb*b4tD>OH?tmCN=5hF&KhbKY?DGD;}>@YYXERS?I9GGdu+tyU#s}kB{0_(aKHeKC@)fK=3V{>f6nBU8t8lyGVA4$eUmGOHkkby5Ya)Y0 zu*pjel4`#h49~{a#3Dl_I)vP?!;_QV#z_B}4qt5RZ-KbJ3$@YrurVpUhxdCC_(Rb? zX12QC$CvD2gQE`cP5>!0n9$UO@DW_~K?FfJ4x;O%`>rvtW@#_odp(a4nqQQDOQ7HS^dz1S95J=r!>pqSuqJRZ$jkuc%3TV`s9c)&v#LB(*2PM- z(r967HJwJD;4gz4UW7oMZET?b8bBZyoq851Bz`ge1|SVi=%&-;ijZukE~hS}o9U%w z)AW_AoW+>l)J)H&meQ9oC56gKc-!r&RW_uJA!q8fMa-}KOikxYLjB}X*Ybpy-&d;M z&;Yd~gc06U^9@Ua7$RvB>vI;%32<|%I$buCArp`(e$SEf3uU2E{1K8&#S_7jS)85& z-C(+x@boh$$_=bli{(Nl0?CK*NuWLYkkk*+?BAeYU= zT`VW=)odc;WO1*jSVmI5*EZuwIE0XY6CRpC-;1$&4)BlJUp(u6LbKsCV;AF%1PBF? z35|3k)95*w2Kv1=@;2M(ZR8q#Ctbwf)aX|UN0g0hGBHZ?WXr^X?{` z>ZE9#r$%EQsus!Kns{OIw%V~~VePoqN$vVx<6MYea7+zrefV{j)l|O*se$faiyuFJ zN*D3lQAd3Yac{w8Yqu$OpfKe3Pu3a-K}UmX!MdXS%>KE#%0j(T_uU4DtM4AK)#m&J z5E3Z5xmu~=r#S)U%IC1gl&UAnegacjbC~$a#v)!|1*+6RdeqC9(%3e5)}kkotFx9z5qE*L7PBfjRcvF`2)9J?n%GtzW5TFg`Joc{q_k@i*i_M1ju6-xV)2H&4 z88g=SJ#2um-%$CI#*mwyF3SU`_cG?NE~|-r{s@MpA-(f5r?PqcRq7m|lrVM2-mQM>xl@Pm`6l-*ny0-)DE?LP;cnr(dpOEif? z-C#gGYA}o7iWb5cn5k4%v6br`NLU|1kV!f5Ogsk~Fy-c6bmFPF^P)b77t^@f{@4k7 zaMek|mSaD=pi4>^ra-#;yZf+>Amu6jFZXq0+Rj9V*Y5%5e@% zw)HT3o7X;E_4NpV^UJR(Q7?w zmCBW~cuVF=pX$fkUc4PpgLs=O_e}N4LOUXqpttpb+MKF~3n=!@Wo&A(&dv+2mKArg zJ~63pMCJSxI1St)C+Es%%5!Gt$e|Vd@t&8Agzv?T83~{PFcO+T;#fu2VMPIj@OCpI z_{LR0_(g0x5T>dlcn=I9Y4{e{Vb*0T{DO8Ug1VbcF{R?$w1gQ6dnC+C*egVSViFkb z&8WwLLQYzsxfJLe0zX|h90`9!V`f)$xma6lEG#yP*e*_=@>9nbXFvvl55P|LGmRSX zC>rhe=vu8|ZnJZ>+CtH6s(U4!eaO~pGYxZ(u`UCa@H1a$eInyU=tPd858rOr=f+L0K)sJ>iJkiV~V}&E*&yPBt2hllU4?mTxCDWMhRy=(z&#rRUfR8A;fxOMkwH5giC9DFyu<-U#*WVs*^Lyq zLcB@B2fLZr<=6${%s4QogAf-wCQ;f7!Y`Bdl=)*^&*6oN#`aDgwag^Y|qAjuY9ij3Xzp`r?1BI(I(5$i*AH%Su4> zV0FI{bp=U+VTV<^sxTg_szUOyG#3^^;tq>FBI{-uW*ZM2DI{b(X|9v{`x*Q&gO1K} z3B|ABg^amOhATyD%<*NxnVdv-Z)RqWgy-W23jO*iK0eLh4G1_1RBgIg)I*GtnB6$uvLe<4=50J>9YiNiV|alul^bXX50u2Qo7^qde_tU0qFpXF;sc=Cttx*xK5m#BJz>k zfQWQ@7JMsj^GcPDW?8Y$nyaL21c9EP=lus6e3-$CwaJ>Ij{vx7)J1<3sl81vT@NN+ zRtt8mK#pCYh?yO4>@X&R88d=WfqY3ZkY;|4*Qz4-rdkGzm7dPfz|I&4m^jJkV zBlRRGny2vFLPcig3AW*;!cQ6K>yPlkWqb6;c$<`B^iMH!YlyWF&j;}0+qmi^lZbe- z&WJnWj=7p|rg63X5fpoH)yV~Eo3BpUolTZgAXULr05J+thRoD-IWya1<0#5-r?QH1 zn46Lgl2OFvlneOg^dgG&E_cpK(r8#fuyK>knC#_(ogY^&&~jJ=(IK)}wCx1V!h^*T zg04I_VnnnPh1^TbVQK4c9iJygYHjT&=!{y{2TaOOM&ZNzW`BHX$|`MO)1F z_oeWGDe5fJ2E>N!4_kc|qJz~KJAw|fL|r(BvB9t0hI{x?LZapEF)WAifyv96SkWB+>!kA_^33GA}=`WG1avkX?8 zv791MFEFwx&e*Xe=4(c#&a(N+*6(3)mk|^ae$GmjHJKCMrw^4Xq{b|JB@lx_R5A^2 z2P#T}5=1~_(d-Y;oM_W)?Me5<0)2Yvj)el_4@} z5U`*Rj}v9ef-Cb?vl8`ueR29E>GN_(q+srHB6gGp7LR0`)bD4*S`(#()P5N+wy?u~ zoGJLU3@`(T+=HwB)}9t3do zIn~F#dAUdRmcd_9{c7MD_hKCAZm^tGL*-ti8-_~3Dm5YqueY2;s?}-~Pkm}lxnIh0 z)tFj~m;rDD{z+oj*)OE1fPpUzs(+>$2GR_ve^GfUHx7ggl?=QcR{tuwu9teQnjJws zS-+IpthV6&>d2Rj!p3M%9C^l3N7kV;Uq%(6>X4jTqqd{Ov9c*KsBKE^P&c9`Yt;nu z^E-~o zyd$hdN%e%kb_o z^*HWsQQs5x%M)q}F}Fryo>Z?v%*&DbsCq5#Zj*01s;G|P>2~{6QpfRhN2CVRN+IS> zQxe9ytIBEyF}qOG33U>8uZYyCqGl1Z+xFzD*}L$LoXGxgWS&xUfb!ka?t8+VDK)RE z$hk-2_eSDtY60>0O8mY^{Ar~Te;?w_c-ap)9uQ7vYrNJ~18MG;y!#`07u6ZWKOpf3 zBJpR{Im927_*X{a&npk{uafu&Bk`|OO~gMW@r6kI1@*m%pOpA*k@(lErx5?J#6J>= ze_Fi(@voNnLy`E4>KVizmiQx)_&2IIA^uS)6TMkI3uU5b0fWb&Ui5hRd(>NSzX`p` z8RDw9s<#PVdP2pgrV!_rA72|QKdHWNH!wx{ap0u4t9PKR*Qj^m?HF^hr)2Csr@kL= zj>^|xD_{SC^5gO@qyC$E7v2>+-vK9N)VtLW;@z>X?|w-AFy58q-SJ3^enh{m8M z%K9z!+w$(e*?0NKyWdg2EAQTA-@QBX?sMw*Du z|C#!8#9x;9_ebLYLivdQaf$yxB>qe4FA@I}692(S{9mcRM*L4o{D&g(f1~~u@y|>A zha>S{R)2^1k4XGSBk^BRe~{;nZvz%#euNP5S6c>cQ7CKh86}6&PuRgs!wCF-a9nG;Q7p|>N+7r)^bppC z-w$0;aK|7fuN7xX+8?6G{8Y7ewpz4r{9aL)n5$IF)tceK2wMosBgYp{Kn^!k^M{~a z3bArA5|tH+0dv(Mbc2RPqsRvc-DWBp50b$jG;bvtem zrpE{sTcHb$4G3pk5zr(M@`)G!F&6)FkT>juTEzW?d)D#Rw0|$qB2<22zJ9__nV$1{8|8^f2zNy*HG!PLAMca6 z_Tj2?u#j)Td1Cki7u`3+Aurl?pj4SNqJmO>7xrnpjs?0kd)riik4=Et*^6RYP)CIH z#UC*C4;i$#$aiN@coR($_SmrF4YxOmua|+3^_DuX!%Y)RHF7j=2MT~dnze_1;3Wuy z3JGuh{Sf_weN;Z1U#wOj+|RcLoDl>0PNN8r{|@Wc1?2t+1QeJ*P|Yf~vOdK=;JoaI z2+!NpUgd5X^f(ePV^XjLX-6J6MleL75bnsLjYG>Zeo6Er4LjeveSeia1PEiu*CHp9 z%2Jfx8Mc<%f4xlEOfQy*))E`%E%Es)kaGZSr4^5|jfP5%ujNZo9D$8|R zN?e92h{O;AE+CKy^*oc|J5l&Us#a>qHYIhcJ+(@MYsK%R^nq@r%6oplBR}H{8E@Q5 z;|O8XPKv02H6bdnVp9S9gtrmA6pMc+0&VAs(qaRA5`trww^|!Xq*1D;`YDvu$FDer z!j)usu8tJ_Hidm9+KH3EWg?oKVAp&RfuAx+()3{(EKs6MKim3NFy*8-|AhHErrfCc zP|>u=U{SQ_t?cCuNbkBCs8eL(Be;TJSDwLi0&l;)|GO8q@{}c->724MRr?PL_Rm8+ zMH#fLgB0!mE}PJ0X6ir3iyuX$^&jD;b68p^fy)EFc)d|xST^}MC}r}sYSfJ1VUUR7 z`VT&Apvx+;2ypxV5}5*q?O)-(1Gf4v5cmGDPOIBNWjo6VZ20-$kM|)iU~h5EQsqzg zVboGcEc()SXE#zRjdt&lR>b#`8l9`}cNL7ua zLBt3$zS>654UFv=J-t|uK~2afKFA@HLZYlQ7$0-Iwe9VVq+A*LBA+tNjcaH)vbn-u zMq`CEOn5i%hisS);YW$}0tTae0L)7C&#}nIj-jLOL9K#zv6uB9cWFxxT5nqNu~tj^ z!E)|gSi^LFygtpI3jTN>_S|MXpaH;cP;@i;?dU5bb^}Han+1W=t%pSp4yimyvuVgN zh{z*N$ZxluxE)+sTgM6F@4v-2j8gKKaTh3_{2gOu!guSkTwOk9TKdVLr8zeX7Q45u zqt7BqMH#9Mk+Z28TrzKV(`HlK01GnTBt_9H3V8J5Aam?LA#!lDR*%EX&tEM!Q^ z+xj?3e)J5ajhv1kHEJ?Hf#9HA#c1f5Px$fd0qDjqRq<@{k zZ!q{Q0zYMtlA!$n)BXeBw&Nk01HVc5Qr?yVREKFcfklf%`!KG-xVNeu%7U|`Dt;1M z99>#@DjUMG+f){ut&w^9^)Bt= zkozLr#a_?3n4uj+zLd^ywav@~QitQ@UOX60D2xqf4a~;SlR!l>5-9c~k(_`n*G6*> zy*r76_9kX#aAAJ#+^evlpjp69^EC*8Y1oiJw;sEr?(-$%(eKU;}Jl)J-ry|ts={+bht&8$D6MhqM z=BrIte-S3y?sbyAjNQ;iHF?DLDW_w_H)oXST$N}?=*{m%stn=xHt>*{2 z)f2Tu39O|`+Iqe#ti`9L7P&}WGm+B!7*DeSN!1@d1#S3Ki62;=n|Z|CV6e0u-6pt( zO58NG6D1~MYl<5=_6({Cw?TmtBdrr!_YR1kH}mqd?1L3q)D|BVK@45+*{ zhz*w)s3k8NJ+(mlu2P+zTZ9dSF)|D?U|)c0>9Y`RqRRF2;AWf)3n|l17Ij!8l{SsK zTBY^2PeQ>x_!Ni(CWW5giOQLBH7p0qqx~w?Fk9_xBf7~UAZb?Tl}GS2dg5p=EiM}I zC8q(y&dbZ~8K4L>RH+wD@kI*-(RkBjjEM9aSoyWQKhB^7D<4DLKL^v-dCHABPXE>H zRc~86CKd%Vup`Rf%`$_n;Kf$FKuj;KNYPqxHr8P^0)yTJYW%#dUbjW#7)tn8RPP0% zO6RE&TYpkAlUL$*d5InQZC)0^HbQp%bzYM9ue;*x%6rKRycfdKk6-XyJ{5YQBL!1W zZf=d~sw?KUL^_6U(75w6>U_1x7qGj+owdpRXC`_Q0T#wByceV>RNOb2Yf#b^VVHfY zq-lnLZ|M_$QlfR3yQ2$Wvq06RLsJ zX+UBI*!bwl*CZ~u7m^oJ4Vac)WbW6}xUA`(iR+t)&n|<{+f45!hDoWwS`=nx!a+#! z-CD5}ZKjC71ec{Qr7XtD1nE@T#)LUlfPYh}CoCl!au!23RmGM06kd3G-3t2g82m1SoOQ010)2BLhA{y^Gx#N+D%mWn@i<_1OpYU)n!PmK{=< z=;?=F1!GG?LB-fFpqeG#Ch}*>nu@}3YyeGUwQE=YmWi9f_aH-U-Hftv1C^6{ zpb}I*Zu>ft02=ajt`jZ2XqM7Z2ku)eyz{JE3n7aZr7+H~xD9=Nmp1@DTm+mGSK?1z zi68X_jq*$WRps+yr?|`O+aso^(88St_^v?IK9l#d=59x`B& z+~b=jYx&8qU&Y^*wDhgYdp%eqfkGxW6@YC%fZ1u#(@*g3g9!Xo9XrvoG7Li5_mICL z3=J4V3VxD(5Alhy>`7G=%uyFalZ^(Yfv&CL{Io=Uz6DK%H4hTi zHJ2mZ&tQN7``I6a(JN#qu)H`^7Iy}^kMFo|)n8+RRg-PDipG@Iodt^-*3&XF#+fXI z@l~FIfC&sD6p5Xj)W%PW&TPo z;4Ve-`$I%l0o786!hQSZD2bwZNzWg^4fxL+(fgo**!!|BxuAcYrpvVeJ(Zz_uyW@W|#+D{{k-;gpwZS`#uK!3_7MsFDO;^ z0?kw&B~;i8oEVrO2myz0xo#&UB6+T)N+3F?^M1_lmAj&tLi$<8n)_wjMpVNuiS;mLBLpx!BE z!s|A;>}GN)!zZCXQosr?>!y z9NzT-tMr@ijX?)49(z1iT?=O0!1;0pIn zuEKtlUw9LKlc2HQ6iJ6VvPO#OMpQ=9y$8Qc_nt^PP)=dG)u5i7;%F3Nm{V(TjVbI` z(UmaQSXv9G0le?Kgq=6*i1+I(Z3b5~0-M;<`ta^ra~FZ~V;0I0=v~P2OQ6WID0v{H z+@xF!w{#S47kUA=b%fh<@$}GjdZJtbCa+PN&)g1M9-nTfv zAoNkVDJFpcI-~@ZTp03_UnAROVJuEe!YdLs&G41vm|aR51S9t&n8)imd$(bzYZzk3 zypxZEvdg11xP|~hC#7Li8!gT#_SS)8D=-q;WJ=x??pyQo&=TgRwKh*Ks|X~5EiCGX zqDzZ&jfo?zj~?)o@*T6baWe+F*sd#y%1r)Bj>Ml`%XWEVSlDEh0sBjhZ<2+jjAbP6 zt-XGZUF% z{*bj)Fd7Z4zJ48FHW|YTp9QpGG_3tN!3uR<|FC;ov`Pv0&0&A{}hoy2TaPEVi}ZHop;43bW=XpqtZ`2fN} zC4|{%*^MyKO>p5bj=wHqi;L|op5Rv{u2NVeHi99SzMaGg2||#KKs_KBfnu^m^mrok zg9wSg8T|HM>J_A$1aioEyF=t4b+vO@IA?*j03aV4cS3g7YSV<~>|4f1N+6OPm^#_w zPXp&c%p;yVX0iTta$y|brOOU8RsIDTIyzYVVf+Gn)-YklVx8O}Qy)~a3wKD0ofP5l zmG};C-9toohp4%3_+c`|dxy+i?b8+KrWCdyIWg!9}H$rKa*3#YlC2K`!Uz`w>g z`q+ruTC{g0hDXw;|JbOLe=gA6Xl>=1O}=L?sUdNH$1 z{1^hHjYMLv@RH$13@!r#B+?}ZbPA|AVfU|UIv6_SuEgI9FI=QxFic!;;*d3s&YxVI z$5tF78zssm3pI%3Xe=6x7Gb7(NfB>MUU9i~$2uZ>eWJsF78L0H2qHTA+s_0g{yJNp zL5dtE;vm}HsV@~IT-MBxcsI?A&MI!*s0cz{7xGY!Jd=DZYS&#@G+-751kr1zl)(8Q-5{Q?tlJ9%#zRkq3H9 zJ0^jMa-j%SJi5lSgEMq27rLqOKd^OHx9(Fd#V(ma)&gi8e?Kn%!%t!R2K3>%?sLa{)^I{Xn`!Qxke(K!s@ zVPRATpJ#DFnExnPK%PHYo`XwF!wD+W7X~br@};~O!P1*z$Tn)61n>0(Oq75~vCTdX z=R4CUTPz-Lv)ws^G6}jd*h|-R(NZqnbs^P)bP;Sd5ypGhAUkw|I^LT|ZzFyc^fDK; z_=v$;55np$F^iLXZxF;%o1~knGeScAB)X+@O7@8m5#x@auK!UmSji#AzXXJi*R+p= zw)Ab&6M1Di2^J!Uo;yg zxC{jWPL!}ypebQZ$@1t$(3zk~A5%pYv=E)fs; z{~~+{nZW`#X~IV(C)27^S|=%V#Coh{acB(XLGXl?3cC`vY@yEr!J@5?6L|_Y2Mj>h za`A$n1wp@7hczs&B}iJVil5SG8^Tm@wW)uPJxqGkuzJiqmv0s=XuD~@=tPQTg^q;7Ct)D}i_}ghzxpk$Fm?xirU5fJE)8 z^>rg^{SQH{;U4jZj#{rs*%DPR8@Y*~=2U!R&8cxk-K(`ShKZ^o;_#=ay+<_BYCynm zx874)FR;=F1Ub9fkl!u5A-*wac$_EEEYPuNNVRr2h5;SHY#Q}}Rk(qX{(00HOVbwo zbYmvz9Z38Qf{L8alsiHu+V$<=>bgl-8A<_%i1S-u1I}c?A^Lq*Lq_3!_--f08I|E= zF=R_)`(IH#4X@U*PPM}B$^X+Mud`nJSfy^5a5c9=%c}M7;Q)(wLab~0mFqVbD#_uiqpOph}WOklwnux4ylW z?FpCFF+>+*7NB*o?7=7%4J-vQ;2E;&6W*;NYlC!&92v8k8B8p?2k^rJzJT#t*Fq%| zu>U{{Zd)?MB+r`g*_a#nXsxyK}* zQSV`W9bJ(aVI_*f54>j({enG=xn%cy|$$K7{jZ z)v%~Gt%{@~gzZ%r@oFJC08bn9HSh|>(b`JmNJxF-W=x2Pkn*u8GAjF~8Xi3lz*wWT z(zZM9AzCD+In42qM?h1oqj0niq=;Hlln>;X&=@V>@0=!Dgpj8P>HN5L;nant;b(VK zft5nwyVr6q@+w-ieW<@eARhfWCpm9;56wK>w z=$^_}U|jzx08tp!f(K*`ehv}(oebX2fczCWDTW4=?_%GojSP+aL9=<;%sb9y+5S?k za6#XSxIiR5j#s`*2>7{$#p7T{io3_U;lW5bH}excqT&GiFx^R*tm1;+(JOuI!v|4x z)^!~?V23*{7w)(mxZ`qDRFL7n6!?#>4WURwUw(+CCVar1B$FctncX0L#C?k@qtUH( zm+!W56IbK=9C(7s9B?d*Z^e4%l^CZK8VA1a=#d#hDDWA1e#r%QK6xQYF$#E!DZL5! z3+gk_0gYcsRb4*u4l^}FXBWT^5WfVTwP&;X36wTOq0p=Y{LphLfxBT5fb^gigN)xDJH6kQuu4kU1rbel zb_DNNLxi-%`wP7&XY?|5lZiSCo5B&&b>UW^Wh|oDJcNi621esAnLqnWaMJm>Luz)R5q=;Y;vatyWp# z%UUb05#dqe8sbH8nMNAxfi169t1r^k{a-@JwP9(a8UYqW`4H<3;M=428+@0y1oIlS z&M97pYg02*`$yE}`W$06H#7QwOTEWfSKMt0MP6I^B^!GK??a){IL5>pwbs_OAT`ZA z7uOH5+~?x;>rqZn|BPB^%djyVA4u~u`RX-%R~?r7_3h~Z>EP?;3$dkwnAxG`;m8?W z+9oO#7tue17#)NG;kuzY$TWaP2-_w^nU@pN#-MId*bb>R&7tCUz_$nR-H5S0tVWu{ zXJTmAbIqZZ;jHpD)$=x0zO6T|YYt*`ZbBGS*IP9(mX>eIO4}U7S9eJJH{14aX%5-D zt*nc^zk&C7V+3{MP1Lu&2cC-pV^j5>nL0Dj-BS20{?JVRv#1v3C&ji@o?>FNA;Mu!I zj04Td7Zafdlb8nQ4eF<(DR1qLD0}Lz2&>97hQoQU-|X7KRB4>8OqcyQ>qF*dw5DkEP=dEoWzhD_;ciCUPk;px+zmDdZjV)6+q};AU<*=K$V9umTaA5)w4o#61nZ0KD(H3S zs$km^e$>0mXj+i`h0j<}zF-CXr*rS}dd){AtF_54Vq?$Eyq~Nuf~}=X?2sWeJy>KV zdfdyv9VczLi)IZTj4bj<{JINmggr@-kljr#$I}>+N3$e&FdeXUX=ioAHYu~q7H^%~ zbs>0!$Ndqmk}TSJYJJSx*}l3NMp@8j5i*AyRe03 z6>stBp%&H2rw9E04GC?%OStV=?WNuyYt=g+^ZHtr>!?a$!ua^y!@T71V-3Z8 z4gDGhIGrn|fxs+{B8>S%OzVQ>ql^pb^nPPq&$Ac6xy3X!{=I&c1%IA_$bxeRWx|xz zBqj(BF_0%t7X2$s^97cg(sjsL8(L(+A_m^eZx@*09D}WVd<*Zk@$PyCLS4Osai3xE zRt6Lt>lA~p@{s~wkp~;CFrm!8k1sxpps>0_@@wo+Lm<$7fTatCw8FtrRm_4jevXF% z1Rex5%kwQ7C_)T8zu+gu5rLmF&ba+V?f9$~LQMoJQVR-+{XQAva7l26WSgHe{bZgx zy4CM*A8xzY!yiT=gJ5M3LPiW(t~28FyMyi^WWkjC@|Si(RCV4EA9b9kh7)dL6zYW; z`eIIya^sZ~`7qhyyrWDQewz^*wM0mr9Y~##htI=tl!4NDY>)e$4AdAi@a0UIGRtDP z9v4-vgVG?w25mSBtEEmxM0V@=pRvYI;L@M4s^FbCeiAGTGgjq z#w{g6?Pym>1eke=fEg$8Kqm>>j3hNKxK$W`@t6*=fywAsN=|NdX-AR*Sr_Q%m{M3S z$V7RYiM-7kf@!vQHdjB6dchYtELo3BX+1W57MoG%|6D@pTu7^VzQxrqOdo1C@tY=9 z-z8|HndNpV`0@aBdjcIB`#oq*$+niQFAR7S`zT~6Swli9_y)So^kf&vHiHFYLiRM1 zSFY*4R>(SG_GP0;0o{&Z9hfkq^hqysw2yQe(hok6Jo@BKM-9WvTi>?obflCu6c%n=l(6>_Oz;_u75!@rL?%Qm0*zlP zN-F(I;sG+y{EYRIZk@i;m|5>(AQ(@SPpE09zk;|x0)7MEa~md}vxRxsF+0Vl;U_pH zsd`BzjufT|CjloCH%=KRg=s*(A2-yA| z%AjVt+)J3Y%@usLrTO_Ac;Gy#Q#&j!(sDb7Xmxi@9Bz5fU808pm*;)01H58l8VKk>hJv69wSYonOx*nWWw74K@zDNNJ=4sVk~56kXrFH9he2w7H%}0 z7U_4hi7%o%y_dh#fVIUdsCCUXD)5glI_`B0*6khC4wladxi~@QbTGZf4TVXgZ0}Bv zU9K5B0&>Yrg)Zci8Tu0<&>n}<`yK5geFBnQh*_vkHf{=h@@OG2YPXe>A__-j?oPt9 zx6Foc{WVkKGpJT;UWnsJvo7w$3!DmI4KNHJLRKkRSUH+IhPvNp2BKa3zr;b$xsk#O zluf2mX4RmFf2h18ZbT*lW8wE7t4F8UwXL+afz3rAjcXsS`W$)@gAPm*GqCO8f@TE8 zS61H$=L114)zRBU`^cTeNkMqps1g?v)v++Hr;(ijKS6I(F5+`09yxn)<>bxnd?Vj6 z>hRHpp%1ly{)L?g{a7AivjZ6VSRSNKtYZUtak7x?|Kchb_EJ|VHBgvrr4e2y-kJ8~ zWO*9WZ)Iv+!?I*RY_|ke7ujj{8&k#V5WYS#yIQ}CDV3NSR>`A`bGHx3451{q{t?6k zUmpecGN`@zK5P85NFh&Z6*!r=z{MPT085H7xDh)*cnSXwy22mju!rCu2Q4c1%Ju{{ZbecIm&z*Y%$vIN&|nwmJkQFW<_9 zZ(vOu$VS3-jr9eN8HfJV5xt1X3RNmh!Ta0F9xt6OVKog4!qHj{sv>eq2B)paHfg+2 zm?%=EkF*>VJ9c@uMV7jk%0J$o@rb7XqshV=__aC#uT;|j1s(cD-U&}v9j0}s;LC{|`dq2!W>g3$XQ80``N3nweAtYR77{gy(?{@AK z+B3FwA(o#O_0tHt&@mPaJOTh9hleRkx!?#MIouTvBY?&e=)jimB~akDgPH0!zF$g{ zBC5j`1v-km1m?hEAgC4oljuXq`cWEvOx%2c02f6Y(^6o}G{N);gNGSBgy6~w5(Vo% z+|a)`@Xt(l+4RchQ55lHahDnVHWUS;7YJP&bxvX3ZLzio7#x&M_XC7@KVY;T1nLOX z;f5X9B3y7k2=n@f@Oi=oki|kHgE+VYY@dyBs?h!jSKx1;bRkJQ zS9n{;IkC+o*r>34t-``gnDwb=W3y?nRE@1fV0Q-iOX(@)w!Me)qkYpOBmmj{P#%{4 zhHVE}imnLj+DpxV`At=0+O%aYgEY3(%Mws}PM?E?R3B@AZ>E;uw;H{FuIUDGr`JGm z_+b$S##Ii&(|1E;*tZr|G5C54`!$w3VCxChzd&4CU9AR}2IVZ;AvOFAY_BW}lni9} z%@*$iBeq4Z{sO)L5r%x>S0%-2Sj6BvQfo8%#xU|wW@D%^jI`X_5|O0TXtM_+evKWY zOogkk)*CV7lQbj@>7;MrG;PG1_^WUg$Kvd5K!8<_+QH+?5@3~t^|<9_7IdDY`Z@&O zozy1_mbv`vmSu#iKz_YgyiQ-pkDDr>E+E^zEd`j|LT8SYz2Uitwh*^!uwX?ZW+YcO zY8o-)rQ6IOIJJZZHe`Qm&UMxIrU3mGj^nKep2qk++8^)>(SJb6W-LWjWc4fX1@Pa( z8HxK)O&01dvO|0sijxy)g%5X*GmeZ5>d219p&@&7Hy+{vY+=k4?ZQRWR4UYm76)5cE(dXQGcA(d1-dmHq}R6(S9DE`v}ILMF&|Ic$`%!q~;n$>vxP z&evGL+Zjh`rqR=VjCUfa%y#h6{2tWE2r2ymi`8(VFgwvoEo;c@r}0?FVbwU8ns2Di z`vl7r5WbUl>>z*8;G-6d4il&ZJdGV_6k&GS*hPzKh_Rnt2isZ)WC8Zoj{716oXPdV z#4@ZY*w#M9lS(tNzwHNmD}xglxHG39lci;@!t%C5yQi}nZK$yq)nPvq$n_>FXpQL- z*n%hMm{m;cuy2rGE+x(aBur-S!Sh1i9#=q%XJQM52F@43fz?2)OVG@i#WtGAf)Y&? z14>KjTbqg59%vyLeFWUk!i0{8sf&yZ23Pw2X41xH!`MFk>p&1-K0(gu+PA&-ZET4W zJs5!r`pj{;gj5s=9I-=o9|JUF5iZlN;*orpQ3FXcg7m9HhhU>-AA(e)l5$W%l4Mh2 z_hIjXatDC^T3=&HF!;0I?v@(z$1dMoqgI>v*)bXqs!aQH2-)yzkquv?)}C@8v7;<_J=M+RKDKnNT8Eeo zY{Th)LVI$EA3=G9J=rn?VoY~UAf1)kS$JA9CAJiWC?uHlhP5=R){E@cz#pCD%tlhcafcit>9*UNX<>QUy@?@*f|d+!_r!xsL4joM7f`AsB(fP0`Xv8h$f} zCo}TL!g%u)mhWiFPdA74wcn>CJM23%>Ti(#84qeI@N+cw>wweB5O#2qbPJNaD_D4J zMNi1cpS=OK*o~gML2ZKy?>Mo+tfb<;LG}*YCy(&Vn%V-yjFghSn(JWk^Z z|0q1;RmY|OiNSURNO_hS?FuI{6T!>v>)Q_i)9HUj`cC^Mi!5up+k$4Rl*K-~Xp9Yf zmkvU4E-;pRFEc(vJsIr8vn~0f=WK|dEFEF_f7A=vU z$mUvGN!iW_Q6hAPi0Xv@{!7gJDF(99{5&?};>AH^)^$7L!rX7uWha!#~kYd>Qke{g0HfEI>5 zJIxFncCQiFn&AXL@Ob9H0(JfEP7B7Mpp|=&cBFt2C|FVt*yh6mm@t!Ga-i#5U_Zj8 zAhzrEjd;_Q9Rn*z!*FSB^`W&aECR&K>Y55xSLy&8*vtBto)kulK1@JRA`{`jkRemZ z>Rb3q_C>P65lkZ+907jEmgo-VfgG77wb)!>xxu!{!hC||b->&nkN6OiZ6VkPQ2^%= zCFUdehwVnZyO>Y%tPJ5pD?m83ON5)3a4dpv8PFz>T!2#vjXE&C-kuOTTKJNX6i}<* zh1~&c(BMS@YsV2#4gFZ$=wIEMzk?qra1-zlDB`Qvw`bc?UWXHs5egb!4zMiWy#%}l z%+O*vBIevlnB@d!9G*GgJ81rQ7>IP_X@ePXtLWDVUO7panf(`VNXx|u#vgHt*;R-u z9Dxh>XmAB$=QA|q0~mru1)LJTp%~QU?KPzkl7@!LwY)DFjTKn|WsUnPDr45JzvbOW z5P)qe$BddajLYG2&T1}LZRiuBbGQu|P#EWA0>Ik|z+sflxo*(2nezZ+hhM2>dD{R< zZVAe=+gsecG$6&?UjRs-qes^Q1<>D=XkG|#u>}nQ*b@#~_*yaBjngEd=?Z`#H3&7= z0`Bv0iX*eQuN!>*gjZSc)7C1`Pl(R)*_(LODhxYKIp%QuHK9 zc(jICBGNFa{Q+d_tfo~R+K(0-Zp=3(QB`wxY=>o#saB9|8YQ*;v1)s8)o(=*oRIox ztelv2aluNcoHEDM;h-UBw~5DLf_O^c04~}!B|AkkI9V4?Nh)6XAncPT{3KXg^@g9Q z>uK`8pTc+a(+u9g;5G(7hQQAdMbL;vVehxJbTZw+_5W9<`IvX1U zTG78rWJX7oZF?g`whYY3-l0DFMc8@Z$dFGT0lU-60dc6ZX+~(OO|vNSLnD$K*hS$y z$!y;Kp{X;K6L4Xv%(){_)11gZj2%jsoH(|IE{f?d5L%s;daDq?!SGPUggkJSgEP#n zpK5NJ1gIq(f6y`*!S?PHnxkdY*Rg61h0@KSRgV!^+#_aEooHiOTE7QJ;22=Efs%uV z@a7n={}zI0p`{{To-({U%;&g^L*w6q*b5Gx;3pIMA@K8H?%xt`;22(&KnPg?LY!z( zfrO^vE@hs@903O$%r@|F5keR19+hhJ;Lz+e!x{I@u{XzY{u__!g&|CJ9n~t0!x8Zp zkx)r+^PgCr=gsic2_H_9>sbe$>x86v)+tK;F%WX4w_udqyNI2Vba>GC)<`f`+G5%d zUU%3TV)PU7x@dJU;lr{7pNuMB$2symj9yNb509y@PU9dH^eOs1=wjo1vgIVwIK7|= z@3CWKtSa%?aqO5GW*n3=I19XXmWJeH@mFx}eYw7?Rlu=hQpsb-!ePcCySJ@HVKamF zArGgJ(I1z$bYb(!*DG^-MVa&Ffq6S~O$@&%Gg-N;p$zqFodKN0X=E7SB$e z7T+X@5thQT8ggDq4M|(FhMY~PC5+|*G9+$V$$CDYkb3IhMP&^+E0dpf)SpA#Te&pQ zRvBKAew%52i@~1YwdR)ulxQjXB+#hv6A%}nkq~1Psp~43`gW!zUJb|?en9^^0=P>7 zUxnU+4Tye^FIWe^za0q22(1ac$o64J0uDVLC4zjWeqEf#O5pKd}@xVL2!uGUA1sVum%;!gNh7V(gcK0|qeA#Q_CJe48N6i1fn&UY9u&!Q_s}U^Gb& zjKVGW(f^(B?7-^7MKitFWngpAebIB_SWI^ML|L9#hQ~BVTkwb6GC%g=SDc(eU;(<2 zCud{3hhJ>;`XS(;F_t)hvdURw#y|_|4+)Uc?qyj{OZ!mgBO2~ZfCm=fViq(3fMZ}r zr*BnYvjC(5M4pHOhqJ_DjampE+YQuzMM=_DbkdG+fmYuQPaT}G=YLTi2lt{NGUPlB z(H~UCV=qw?t(+;Y3_d}09@avf9>6t66mNyNN)Cz^&liycp(RIY4oLraIV`4IcESGT zQXQwsf%?E1bteFU$Z+WKGdSZ;YGu^feRPjbGZ2X%W%z#Xh}EsS4@lck0-pi=m+jc3 z(=}gp4yVy@gb0ri>{$8a4{=Cw{^YXoS{Bbij~qw1bsVSEJ!{+8;y6p-lCkv&Zm82r zy>C#&j@d6%2P7^bq7`gtNhOOI1Y297m_e2*cM%M5=D~&!BMp=@$WTj)evcVWR3p`x zhLN?%9{eEWu&k2NaTxYa$9Qb@fp_z`ITDMc9Kh1H;zUl&%9F{+`CkBQ*5nxXaFCN8 zpF~gGh*oRjJ|no5ZY1)2-tFK+m`>`L?nCWBhOd^7vTL|VWZ(i$HYbi4a$a3V(glb@ zdKNiX?wPIZnHY3q%pL`sYVpTKA%~5NcounlMR=EHz%kALSHUd|9y$!+V3GAj|7n*I z+d_b*U9igjG(keLKAR$s6Wq!U*H9fmM3%Pw8g*efpJbH&J-*2iNf8f5YKD6>j=XSp zo3Knu7h=FbD<+BE@!ktbZxrJ*Ro@282<@0zD6Qfi=5?2i26mSFV(fnt7gF%yIpoHW zrl-+6ykvbv$b{f?1 zY(Gt4_4iuM6Z(Zd&D!$~gl6!b!P2YLF$vODh!bh`->VD+ltyKjz4ae%sM;HPjCHqaq&o!ejNnsBKDZ#`riL4(~+8*($v1foe3 zl+f&?fiZ`TH!QaRI5{g{frMX>!ybH(zB>9$&MFsU9uy4JB`6{&9nPF>d03+D-Jtol zOrRu=%(@c{=5e~3g44SH%qnTlC2gE9j9=lg!4Rrhzc@ptW8MpJm>DKQ$?Mr2-MFpY zI`C6WOb)D;UhK+w)z9&L=OSyyqUkDOxNcwv=aEz-dGP3Jn680bj8Zof)4Av_E2*vL z+3Q?vWN3c~H|PZ{ut3s8-EsJOam4QnStjeS{J170`iDb*@Uf*A0@(?kpqtDRh~^(c z-ZbPV=sl3_uJrUP@atmf$l^UczzAoX7We3HDG!Q>7)|JPNXQUoE(vP3OJ0OkTj-h8 zmk3@#mOqD@Ydpog!Et)_!Oj-`jmV?8%S#qG4qyrly4ori8v00ZXra#tghf{KP8K8m z@j2don8Cvgr0c0F3*B^Dr1Crfa}vO-SO-FHIf={kT58tbyZRT9{5JOIHr&ue3rb}6 zN+l?X$kI?tl*sTVL20L(fZ0}8UhgCt+190;%qZM+>0`J-H$X&&Zo!lh)p42504_Y5 z+DYVEY}T@M3PGgTl#|ES9|j?t3i?H~M_)w%ycu?i>7&-#ClXDU#RUw4 zko|6qW!wA1x6-u9!-vW<53^rL%=U{cT4dXhORrx+nkIRcfj?X`D+dASuCIJrA_W ze@rQ+gB(nD_&p)%&Vqw9>D~5U!`x;jTayC9BLcE4s;K`0alT7NV%Mc~*dWR1-c=Dk z{mARY*JDOfS0W3|iB39xdB!$i5xw#fV7&%61_09K5MGlLMAy}zZ-=ZfJE7_09|+XW zOmI1@3I?C)3)y_o>gyd%Bw ze5dqT-^}-a$)NlA5woAU06xTDw6EbxlwV<%NRE{Oa{$$70j4WZR?GWf&2IsPl!678 zfWVzJC_-9KJfXkNhJ2$-YpjTk)=P_Q45=qh1=Ez3L~BgGa!Zb_)RGNh_bzKm#OAN9 z+bK;a9d+8Y(GBnfT@CJLd!&sou#NwY0H?`x>D|alXD{1;T)cuLT3TU|IX2?NgZ1&wzm<@t%XNm_T1PV5ta4MVKkl4}y0%!Il#S z7ukDP@Tzly*?ka@F38Y#u|r0X3RY>N+2LYOW3&~}DP2i>ld)}hwvqOC6X2XM0a-5i z$AS>5F92-k5yVsp2Bi>!6As-3$8i6NRY#i2R_b3tqu`HXp}u@A;wsqLRBP+I4>BEi zpLsvqN{Gph4TBCX>}qRg)3-H|<0~9fB&kdj4IYuh<>DcsL+aFy8NnA2_!B7TBeulv zflWU&>}tBMrP5)`x-J{G4G%L^?OuDEa^>28kJMgfgfK+Hjj_p

Hm624l;)@7-bhre6&UB3;oV{~r1TzC z&8SGW`drAWuW&RU;MO&|BLi6}6 z+-%O0q=L#hH>UyG#8WB+ALB*7DkMm%HJ-7hfgyx|t91$@q`(~SUCIm8xjV}<+aOcc zA^CE+ZINM?vCERINZ$s)mO&k=o%0bxf8+bF$8gpKRd9Cr$-{8cS2j!-0lxIb9=tML z^U~eGZ~PLwVFNPs!#2{e34#tWd&%$8DJ)~+u^C`s9j_nYj8cA_2 zKt&W3*uP?KO8iZT57L?xkvSX8TdF+buw-ae!%neff9!+L4e!@~MVNF0hb8s}ke??o zhLJMZMiV5m{=L{;c}{ZqJ@6lE)TO359D~0!Zg@@O64x?MV+hG?mol{NU`lGAV%IENHcJB`WvZ1@cGox;9P4Mg{%V*K?okOa8;xpI z20Lr`SH->>r2tc;={RP#hqOf_JKL*pkRFc7g6{(KTNa8B$wn4tiKqeUkisFI?8~au zgxnZ=B(jnNWDyI#O{9PAfyUBm+G#k-9A!*Gl{lz>Qgis5HAL7W)JydeICN2?J~4fi z!KVR1{X4wd!#i1OTexVT6Bqpi6Ftn}518kJy!(CzpJ(ug3|29aVt=1W{*b}95r=K$ z7QT|nG|syO)KSD+l;6`hzkoB1unEvlhO^crCq$7$w2Gb<$)e{)?L>jxVK7qkuNNpd*NP;v^L9Lk7M6ugzqNp%y- zghiQ+wGLXi>vQq%V#4fd|NlPU9ILCdK)(F<1TKp{k9Y%iYe*AvGU>dDf-rXQ_|jr9 zn_e)g*Kat3K_U8Y*|9>)WOR}}F9SiA{SGmiaKwF%kS3_j-`@ij^`mZ>>oBmgK63*yYuH4J_cJ}h1EL0Ift`p*b=(CW{ziIPY&)&CfQU7gz~ZLYu?zDCjiveLE*{@V%6 zgx&%#z-}dum6omufF1ROf-@_|RA{=7)fm1zQYvL*aICi84;xviBhMg3GxdS^J22*} z5V6(|HdFf54LA^Jy^%dGBqtC_y4L3_R&UM{Tl14rPjQFEktw4SV_yi&by2dO>hXc^ z4Vc-7-mfKIPBHYeEh{g-H{ujiu%jVIdpj52y#Qi_7=0%npJVWY3{ErXzR0p~^f&R| z?-f%gbEvzY6Ngj55%2Bmt^OqP+{DqqsU6q`algpZ>d3aihC&z?#=rzJ_pbbMD)_dc zDWWG16B!npa08&4g)?;REK8>)QU%D^HvSt@1{>gi#=U`qDExInqk(TL98!%V>DB#g z2S3WXci$`8lq**Cg{`)#;U*`t2CxaOO%6|eNZWAB)ZqR zTc%}oCiG>Pas$_@GkNK#JI`H{HB@SkK3@~9z332dHL5@9IY%e3__HKSb zhJ^0curUMI{d9}RBEn|9mfgW-ZAf@q+iBO8vMg&GnC=fM!sDE|y@C2YE87(`qvjJ>AW1Mo z)>VeJ@^rZpfTusvsZZBE!?JpXiz>O50wQkOv3v%#GyP|$&ns8zx@*nn?lY&;bXK!U zz>NaZ-u7+-ZG~LR>Kcr;7f22TQ-~y`o$`KW8t|!97t4CjN)>I9D3Y)qcIiq4i6mRG zD*9Tq3LWStkHfp$sg=KLSr_**)tT_4-JN+dP1_gQ@SyQVsn!vXAunaIMrK-|%VBjq z!cmW%v#3UNXhnRLqmQaT<_O$Ql|sK){AXHIz4jG8ki#CPXVvp)pKyd*)=n$1WV#+$ zkKAU~k{n?-Q;P+^&|?8L4`qAGDoNRgoMH1Os%IJ5PB z0`Y|)B)NEhDiqVg07e= zT0q;tBX$T?Of(*_RK*}^xW#k`Rg1WE1>#_Ul0(um{5+_S%(`H70q|srK})e8B4zMw z&);a61Ym&UU9kuHiHWmdXz__9LOUERh|>v~*DyaF;=Bgl3oSH^2el)GUO!E}a4d`l z>>b2hOZYAl9ZHf#dDc(EfvV^jbP7=Y^eIE->25;!wFb-WhZ>wkaSzqtPyp-iI|z27 z&}?D^KzBeI(oPyjGAG>s=sc=##ZuZ}Pl6%D&fJ0nx@IakG*iW-p!u}X@qjNoJ5a&h zwk$m$0Feoa7qZZXQdEPMpap8v!~d^LE9>ztfcQEL>}5c&!@>D@!5drlLc__U4s@?F zW*U$M1AZ>Dn64S;_!Z>BX#wBvk_VE{EqHA4@cdj2-X*3R=Y)CZ_pktY)?Z@pbxeSb z29z@LRhMpgFS~`SMJ8d+q~ScER|4Y&fO;Q(>Ig>j!H4w>V_wgg3~WCji)x(LhZ%Q*!RHwW zPATwCxL9A}ooI=Qe+-cw-l+hqUVma}NoN!WoSS@ z+j0h`-^R4>VDK&`NgRN;jgRooIXI&~&iGF-_&G-PMr@tkfEQo-%v#pA*4LyL34?R}Lq!6xzmw)vXRHt!>~v%xLUUvRq@dIQ#-#KT%o zM!xk(tsW$rET0H(YYlxTQ>B1P!4%g2ht*A6A+i3y@??ds`djj3<%;?{!4m~q`YN9E ziwqp17+mPJgW_!koi1F`k04Hy844R=%OBHOCMI9PPuuOf9zc|z3AV0!n2#gDV{|90 zSIMhx`#!yzuZEXzxAYiZ=o75xS|-Uww+nh5qXtpAHu7Fy!{{|D(8qc`-?Bx9=H1B0 zq)?dpI=L5ormyFHF1p6+&5T;r1z~EUX@BjCh)~~%_Yo{C`1lrrcPoM&XkDFzN;U@l zZ>)mu|8;PLSO!OkWnAamPy_!K;;%Sq=l?pH?0+~12jinjDC;Gi6g}O;YLAzbeK9*S z;^y7qbTl3+;PP%mX1LcGFzF@E#^=*culwy0e9yu6M({l+nf=zfJBPQA4UT1o6At+L z<_i$oyf}JzBsZMSric5oJ;V4C&VI(f;nZ*o_(r);spH*z3n~W2?uqV;MZ9H-cHFQ=liy7>UK`9TTtg*4R zWBp@k-1UrQGFd7PFaPH_>*7w|y7*YyadFp+J7^MHM?v=6P(^*wDd6oOE~dhXAEs?B zc;{Xm8y!nIa1dnci`GSI&!@I`V@Wt6O0=b3_I@mZTJ^W3>1#dpzo;iLObQ3|k8)O~ zAg$x#!&TDHPMcXUS2=Dbv$&LQ)M|5eonQi|Qq$ZGL6(bIZeAqutZ(4hB-y0@k*~A! zq5xC}|I3)VQQRi$vvH4|H7>=4dhC@96&0Mrsi{$>`xtP;t_K*9kT9p@?BLxn0zbJ3 z-J`mZQIh`C4=`BGSA9pGcw~QZ-vj&iz3SlP{r-??q&Xo*m^r?K`tMIM;Qnya5G-`iNocF zIXXvHZITs!?vOd>XTR3KmuHya0}K`!`26-S^N#bo+r;-XyNxmG-AEd%|1bhqJd2pa z0uf^SAr}a*&VO`X1^=4P{~IvJ0!s@7Wcwk+qXN7=5R^uNN%|j?BuI|sCpZP+C{cjf h<@YO(c$p74gUY!F!-9U-6EF5uZQL4 z?(pQ1{{m<4eBccuHJ_bdcy-ejG_TG}7MqOvcKCGF(w$Exau?^fE*ZOq;e4O`2)$J2 z$2!E#I!j(ga&z=~(e6U@t+`NADoa5#nOKbnwyi)l30?Y-I_(3tWnIZ*R&V;^V^m^P zk6<#|v;`Q|&)P@bEh3HDMsthbbRKP56!eP*+v}=Y$5^wrrZ$CZi6CD}mf)75_BAJ~ zw9Z!O?j(wyIMIah0k=esC7BRX0V=iNOK9`%wxuO2Ut&KF@kJgKeK+iCZ24?i73dRovz)d#F|aCJSSUk%2V!nKn+?_ngAD+s-Vouow+DAZ$>%mkdT1{=n2#b|a5* zqX!67tiRN4)l1v=B9fAxt!jdRtroJljd)Q|VN`M|e}CP05RjFk?i&Q-+vQMsd>r749{4cUnN z4)oL2P;d-V8YT_wnir=%vdRFZcoarBLL zyo|VwPTGEaa`XP77KB|nvQjdGNHInqeS?V*#dXHP%-^a#oF$>zgvo{Q*sule48 dezc3x+P*#A9^T)6$=x!dd}UXBvyE?W{sq>mG|&J5 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/debug.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/debug.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c575d58ec57d3ea5caa196dee057742c0fd3815b GIT binary patch literal 4007 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 W-*MRch}V|^8vUBaTL0Pp$$tS?EPFx# literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1ed7bc3acee1a475397f6e90992f050ea39b2c7 GIT binary patch literal 1351 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 ZQEs>}ocLn&zrwt_E7*m-g^}EA|1VkMDRBS* literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/exceptions.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d37af20411a8df943bf267b4c5b376d7a13448c GIT binary patch literal 5550 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%0DN;%^g(BeJPw@@&U$KuKdhF57AH>FkI|k8y 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 A>i_@% literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f329cfcf60558e56a9e271ffd105dbb9c1958108 GIT binary patch literal 20452 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 PY=3&Od!V=By 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/meta.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/meta.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..967084ec123b97632898b9f0b5787760533614f4 GIT binary patch literal 3831 zcmcgvTW=f372X>!qA2<9*lrt)UAr<7l}w!!MUB{KD$B0gLJe#sLD{D3;m%N8dbvx_ z40SUFxR8N7^iSB2`4jyK`2qV<6n)A+DEg50JF_d1Zq(NGv2F3IJqPCpP$vGgkFp27NA z+~;tg$9Z8yGw zlbp?OTs&KDUP&_{HHf7(5RYUk6*rlpFAo(TNf3+c=}xS&bR<&~(dPLpC|~riK}e_T z!vCIdyS`Zd(&@XRDr&Eq-9Xf3MFgS(-z|s+tgXVIwPMBckw=@|`j<}NbQj=TgK(Yu*v+ZN8Pcb)Nlr!xWWlCOE(o9sk8F_Pt5M9CTlp9InL42_9BAil9-R5;Ex+Dx1$jkJ#!}_=FpSgKgkkP$Y4XdH zRLCgdN{TQR@L}AKrP3`g5424Bs*c0Ha`S~S1e4Zb_?7doZfB5^+GFawNC1?d?Q%U|%PRd!6yV8D!}P?Vr5g(Xo*~9>aTlTk6g*PKW$X zXCw`8kN4Fg&O;SBnnHKhZMp~Vp6coLi5c$RcU(o;vvw>*xa5+9=7TIF`i^!BEr zGg_Wn#*ex{4_YW5=RxHa%XkT-Cg%sv!S_zr!}8^oKBePZicq}B2pcoXzvGy_ab0KX z4!xoOI(XweaK5kHU%1aabz>S#ond8I-El!X!`kcmG@yOYo3;-9gPV`x z<55p4#*>82g2?8A*v@OHv@F??o2>;!C`I{(@(ZoDc}?$+dRe0LN|JGbAGl_uZOHT5 zc9QjYqSX>@^SKbMO5rW?N$!SumD`fdD`O7Z)fp_${HNZ*>lNI(iAU4B;$1{6y_dna z2iH&cdZDDH3-^IihTj8lsrA3xbD zP-_tH2pVbFJ;6Dh_D!Cqj8)7lkkPb zW<|3!GwfNK?WSyZ5Jv+mX?Fbaao8@HkYkw&f@@$qoi^rXU9L$u~p>-@wsE zLTY(?<;5-Q+i7st>IK*uYumykHStgjtY&el4MbJ;_K1BysJf@sD7IIhaMR%WWmA(37 zt)(I()|JZCQzj;g)F{%YZ0@OGobndU9_Ao*k45!?2QUm8^~(`~MLcEEL@BreMi)ny zQ$r-j#jv2+E^4u`3WZPAS0GSjCq}2R_yeH+5!Uk>HB|J|xw^Gref57v?mD(<>Z^?l z4Y%s57Ra|smk^rZA;PV{#^cW@-PewB-?%{LKT!b>fzHOCdL|fFjy(PIlCI*t*7uG) z_0uV)G{W&iAK(0fPrXm{aKSXd(IM(H2l)L1;TFFskls>Nl2`IQAnIh*g``F7<|Rkd zEZOroapAm1c^;h*PJO%Y)92M=xkcmSJ)qM=Bou-M5TV3SvX2ogjZoaPDUATdeg)_N zJ#2Pa94Km*@ze$yEy9jqEZZr24@n$wB`7vCffx*pOf?OPtAMj8nOGWPL?OqPy2eQx zeJ1t+;Bf@Lfkc1iP>tEqu-ryzPQ|gxo^EETe9B6IvXb^=nc(FA7o=Fb;LIBd-^ZNW z9+**bgRtdRVJ3=tAQMblSepZwB-ZBk3}t2^2v0&_QKo>TKdj72Us+{j^%n(@*ub1r zSmBudB(cL~0o8~s5T+bY;oygGrQG8LN-XX(Xw7zcT3|JBL&@GGP6S|G8BMK-0=g@E zG^R1$ry}R9Q0F9F5OB?+0Z+Hd@zjPkTg!RfmLakXEgA-fW`8VoUOzT4Z=j%4ZNsa4 zlv-X{LwcCJvNeHjdGK5KNKyODD?2=yNOhCw+6HBhka@)vY~)HHg++vb{y|Wy#J6;O zj-3-uhltbMeh-`Vhj@4|m(Nw*rgz?JxJ|$5)-kWteea*uMGvbDcR6Ud!M__m0g3n0 z`?g*Q{-%D0jje0yhonIj1_Lj1*W^xNV7=_TN)gW3IV4}&`u!*C;o7g(*M76H`Dkv^ zA?VBNTO}6f{u61e2P|miwRI{eOlggWs8qBVbjrM1{Hi-7{XN=W`7}k%VOn}D`&;mT zUf(DyHn0EALM~6N(sK^7Q;-GH`bWiNb)TjiP4ipe)cvN{#PC+d^Q?dE!o@4s+?)P? E00~Gqk^lez literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..564fa16f90adbd42aa7f46c681e2b51221e5ce40 GIT binary patch literal 5026 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 Q-+5={{K^X}OXVN@8-pbHM*si- literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/nodes.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/nodes.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bc2f44f79dd7d2a06b847e357002920cece512b GIT binary patch literal 40317 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6cbb23e2f7fa5d123de09e01795e92f713a6b75a GIT binary patch literal 1971 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 b=i!!f#84x89})yYqEMnxiT^8~AI<+i2K*yg literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0814d97bcd684fe57535b9147e8d8ae98a08ba14 GIT binary patch literal 32164 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3938a366440e4eb5d85b9c8c18fa7aaffdae90c7 GIT binary patch literal 24524 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc b/env/lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c10b2bc56e0b370cd3795b45a1f954ca1a39f6a6 GIT binary patch literal 3990 zcma)9TW{OQ6(%WCqUp=V=_2a{o5i$UAW<(?ySpz1wnYqgyA4`+gV@NT>ZTOU8A((q zQkkLbNR@#CZl4PD4-^HGqA%N@(*6U!6@A*beeO&9okPo#>;$L)9+5M{Gw1q!!+diy zu<-lWhksOGZ(7#B>0$Zj;^6@<(}s{%+mg0)QoHTQnsn3J&~3Z6rJRAM-{qNlyYZ(lL4Lr6<~HSAwJ3CSqO?h} zo+$cC>>VD7ESJjciig8ds)i~nloZDko{jV2C`pwTQ6__-Dk70&h0e`L#YK{5yTMnm z+dBBlhHToUdjL%_4K4qCJUqZ$7uiyDl3r+b=ht zBqk~Lqcn|^2+8MB`pj?vM#lyP8yCV%vLbqc>Q#!0QBVxUMOa05oN+xGu5g9= zo&*9vsum25Gr23o5vu+A3&Ut4ssa)xQ94#eoc5ErFHRHaKUS;;ZG%#ii?-;no{m6A z^mDlz@Tx~>6REnw9tg!3r|Vh)65Z>D=RG;k`~re3#Y4X=IF`#EQJjifB3P zKg>lWI!Ai)vm}G_lTPIxzkeA4ahi`)$%>AlzEZyQ4#y!e@T?!5B!GiB%J3lKew6hp z2Xll^ClUa`Y6v7cJynDk{&X()g06>M7;!DCLcK^#Q6(c{D_PV1ttCGwVDng(ssa59^s7!AcyPu5+h@$k@PnLn==?WT9lTo|x<1#xC zg*5}x7WT|Ow+GIjt-mYtz3!W;A(i1}psR!zwN;M6Yr}B+Fr7BgxREC=~OT zC}tUyM+G8p6mN6keC73JbVXt=HC+z^=`ZV5dJmelvVjamMWIW#n2eO(f|E^0Q@2;) zx`a1PP*AQfCG=ekFb?f_({~OQow&QSW&xBdfu*1lsxZtxz|G8hY0d0c_L)0#r9HOw z+cS4&_w1STSNpM*ShL#S>_6FuST{iMua7sKX@&SGbuRk@c<~Mtmzygk()5;my9Dvl z?k;e=a@6AxeH$7KRZQUc&MkY#nQkvT%4@DUM$WNg-@(nyerdh3eri44f@@^Fd)0W` zdJdOSL(cR^#8*_dTo&rZC{5y|xUA|qS}hmI!rk%)2tyl&R(@-EdVtG3hPX~R${WQ5wZy1C84u z(3w@_sjNDLL6|_gQd;RDCY#g8RiyxyId0Kw51oGh ztbx%+QN!p*=y`Y6xZ3k)jafrlV@o%mZ_n47k7o6k-mLM;1|n?ZzP`Ahc@ihlKR6!) zD|koJeayPOYr6fJ&$_=T8Z+R{xkCt3_;f$Rxu2e9z#C1zHP^~@hK+8bQfbNnWC+fT zvKXi36l7fWFg0yiS1$^c$+8}eM)cp1DrM?un2JN1Yp(@Yk9C)8sJxJmN@b9#)9Tig zUNz*?5S7#tEHEMv8vPiTxesx}4s6%nu47-3I;yN7ODKm@veaWbR`8k|Ce!Iwc*cyv5P zBUL9ru27=ni_;YIHCk6?z#Ft~BuImZs8#4&rRspHcImZdt-@0Qv-LM2-hlRwKDiRt zGT`n%Mh55pUkn@7KT^hvn?^H27F@$lf&a=Tg=a)lZ~ z+tMji>Ej!$$m2Za4;Cg7R{uI{O8?{PBk3pf{bz`TT+6R*ICaOjZ#rAv+u!;h3QZK2 literal 0 HcmV?d00001 diff --git a/env/lib/python3.10/site-packages/jinja2/_identifier.py b/env/lib/python3.10/site-packages/jinja2/_identifier.py new file mode 100644 index 0000000..928c150 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/env/lib/python3.10/site-packages/jinja2/async_utils.py b/env/lib/python3.10/site-packages/jinja2/async_utils.py new file mode 100644 index 0000000..1a4f389 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/async_utils.py @@ -0,0 +1,84 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return t.cast("V", value) + + +async def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + async for item in t.cast("t.AsyncIterable[V]", iterable): + yield item + else: + for item in t.cast("t.Iterable[V]", iterable): + yield item + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/env/lib/python3.10/site-packages/jinja2/bccache.py b/env/lib/python3.10/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..d0ddf56 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/bccache.py @@ -0,0 +1,406 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: + ... + + def set(self, key: str, value: bytes, timeout: t.Optional[int] = None) -> None: + ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/env/lib/python3.10/site-packages/jinja2/compiler.py b/env/lib/python3.10/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..3458095 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/compiler.py @@ -0,0 +1,1957 @@ +"""Compiles nodes from the parser into Python code.""" +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "Frame": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "Frame": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in (self.filters, visitor.filters, "filters"), ( + self.tests, + visitor.tests, + "tests", + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(vars): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, public_names)) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import exported, async_exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline( + "async for event in parent_template.root_render_func(context):" + ) + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline( + f"{self.choose_async()}for event in" + f" context.blocks[{node.name!r}][0]({context}):", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + skip_event_yield = False + if node.with_context: + self.writeline( + f"{self.choose_async()}for event in template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)})):" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + else: + self.writeline("yield from template._get_default_module()._body_stream") + skip_event_yield = True + + if not skip_event_yield: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + message = ( + "the template {included_template.__name__!r}" + f" (imported on {self.position(node)})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/env/lib/python3.10/site-packages/jinja2/constants.py b/env/lib/python3.10/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/env/lib/python3.10/site-packages/jinja2/debug.py b/env/lib/python3.10/site-packages/jinja2/debug.py new file mode 100644 index 0000000..7ed7e92 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: "t.Optional[Context]" = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/env/lib/python3.10/site-packages/jinja2/defaults.py b/env/lib/python3.10/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/env/lib/python3.10/site-packages/jinja2/environment.py b/env/lib/python3.10/site-packages/jinja2/environment.py new file mode 100644 index 0000000..ea04e8b --- /dev/null +++ b/env/lib/python3.10/site-packages/jinja2/environment.py @@ -0,0 +1,1667 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping], +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: "Environment") -> "Environment": + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = False, + ) -> "Environment": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``,, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) # type: ignore + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") # type: ignore + + @typing.overload + def compile( # type: ignore + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: + ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: + ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "